first part of stacktraces on x86_64
[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 2358 2005-04-22 22:01:51Z 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 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
895         call    builtin_asm_get_exceptionptrptr
896         mov     v0,itmp2
897 #else
898         lea     _exceptionptr,itmp2
899 #endif
900         mov     (itmp2),xptr                /* get the exception pointer          */
901         movl    $0,(itmp2)                  /* clear the exception pointer        */
902
903         pop     xpc                         /* get and remove return address      */
904         jmp     asm_handle_exception
905
906
907 /* asm_wrapper_patcher_builtin_new *********************************************
908
909    XXX
910
911    Arguments:
912      a0   contains the class reference
913
914 *******************************************************************************/
915
916 asm_wrapper_patcher_builtin_new:
917         sub     $(1*8),%rsp                 /* stack frame (16-byte aligned)      */
918         mov     %rsp,a1                     /* pass stack pointer                 */
919         add     $(1*8),a1
920         call    patcher_builtin_new         /* call the helper function           */
921         add     $(1*8),%rsp                 /* remove stack frame                 */
922         test    v0,v0                       /* exception thrown?                  */
923         jz      L_asm_wrapper_patcher_exception
924         ret                                 /* call new patched code              */
925
926
927 /* asm_wrapper_patcher_builtin_* ***********************************************
928
929    XXX
930
931    Arguments:
932      a1   contains the class reference
933
934 *******************************************************************************/
935
936 asm_wrapper_patcher_builtin_newarray:
937         lea     patcher_builtin_newarray,itmp1
938         jmp     L_asm_wrapper_patcher_builtin_main
939
940 asm_wrapper_patcher_builtin_multianewarray:
941         lea     patcher_builtin_multianewarray,itmp1
942         jmp     L_asm_wrapper_patcher_builtin_main
943
944 asm_wrapper_patcher_builtin_checkarraycast:
945         lea     patcher_builtin_checkarraycast,itmp1
946         jmp     L_asm_wrapper_patcher_builtin_main
947
948 asm_wrapper_patcher_builtin_arrayinstanceof:
949         lea     patcher_builtin_arrayinstanceof,itmp1
950
951 L_asm_wrapper_patcher_builtin_main:
952         sub     $(1*8),%rsp                 /* stack frame (16-byte aligned)      */
953         mov     a0,0*8(%rsp)                /* save argument                      */
954         mov     %rsp,a0                     /* pass stack pointer                 */
955         add     $(1*8),a0
956         call    *itmp1                      /* call the patcher function          */
957         mov     0*8(%rsp),a0                /* restore argument                   */
958         add     $(1*8),%rsp                 /* remove stack frame                 */
959         test    v0,v0                       /* exception thrown?                  */
960         jz      L_asm_wrapper_patcher_exception
961         ret                                 /* call new patched code              */
962
963
964
965
966 /********************* function asm_builtin_monitorenter ***********************
967 *                                                                              *
968 *   Does null check and calls monitorenter or throws an exception              *
969 *                                                                              *
970 *******************************************************************************/
971
972 #if defined(USE_THREADS)
973 asm_builtin_monitorenter:
974         test    %rdi,%rdi
975         je      nb_monitorenter             /* if (null) throw exception          */
976         jmp     builtin_monitorenter        /* else call builtin_monitorenter     */
977
978 nb_monitorenter:
979         /*call    new_nullpointerexception*/
980         pop     xpc                        /* delete return address              */
981         sub     $3,xpc                     /* faulting address is ra - 3         */
982         mov     string_java_lang_NullPointerException,xptr
983         jmp     asm_throw_and_handle_exception
984 #endif
985                 
986
987 /********************* function asm_builtin_monitorexit ************************
988 *                                                                              *
989 *   Does null check and calls monitorexit or throws an exception               *
990 *                                                                              *
991 *******************************************************************************/
992
993 #if defined(USE_THREADS)
994 asm_builtin_monitorexit:
995         test    %rdi,%rdi
996         je      nb_monitorexit              /* if (null) throw exception          */
997         jmp     builtin_monitorexit         /* else call builtin_monitorenter     */
998
999 nb_monitorexit:
1000         /*call    new_nullpointerexception*/
1001         pop     xpc                        /* delete return address              */
1002         sub     $3,xpc                     /* faulting address is ra - 3         */
1003         mov     string_java_lang_NullPointerException,xptr
1004         jmp     asm_throw_and_handle_exception
1005 #endif
1006
1007
1008 /********************* function asm_builtin_x2x ********************************
1009 *                                                                              *
1010 *   Wrapper functions for float to int corner cases                            *
1011 *                                                                              *
1012 *******************************************************************************/
1013
1014 asm_builtin_f2i:
1015         sub     $(14*8),%rsp
1016         
1017         SAVE_ARGUMENT_REGISTERS
1018         
1019         movq    %xmm8,%xmm0
1020         call    builtin_f2i
1021         
1022         RESTORE_ARGUMENT_REGISTERS
1023         
1024         add     $(14*8),%rsp
1025         ret
1026
1027
1028 asm_builtin_f2l:
1029         sub     $(14*8),%rsp
1030         
1031         SAVE_ARGUMENT_REGISTERS
1032         
1033         movq    %xmm8,%xmm0
1034         call    builtin_f2l
1035         
1036         RESTORE_ARGUMENT_REGISTERS
1037         
1038         add     $(14*8),%rsp
1039         ret
1040
1041
1042 asm_builtin_d2i:
1043         sub     $(14*8),%rsp
1044         
1045         SAVE_ARGUMENT_REGISTERS
1046         
1047         movq    %xmm8,%xmm0
1048         call    builtin_d2i
1049         
1050         RESTORE_ARGUMENT_REGISTERS
1051         
1052         add     $(14*8),%rsp
1053         ret
1054
1055
1056 asm_builtin_d2l:
1057         sub     $(14*8),%rsp
1058         
1059         SAVE_ARGUMENT_REGISTERS
1060         
1061         movq    %xmm8,%xmm0
1062         call    builtin_d2l
1063         
1064         RESTORE_ARGUMENT_REGISTERS
1065         
1066         add     $(14*8),%rsp
1067         ret
1068
1069
1070 /* asm_builtin_checkarraycast **************************************************
1071
1072    Does the cast check and eventually throws an exception.
1073
1074 *******************************************************************************/
1075
1076 asm_builtin_checkarraycast:
1077         sub     $24,%rsp                    /* keep stack 16-byte aligned         */
1078         mov     %rdi,(%rsp)                 /* save object pointer                */
1079         call    builtin_checkarraycast      /* builtin_checkarraycast             */
1080         test    %rax,%rax                   /* if (false) throw exception         */
1081         je      nb_carray_throw
1082         mov     (%rsp),%rax                 /* return object pointer              */
1083         add     $24,%rsp                    /* free stack space                   */
1084         ret
1085
1086 nb_carray_throw:
1087         /*call    new_classcastexception*/
1088         add     $24,%rsp
1089         pop     xpc                        /* delete return address              */
1090         sub     $3,xpc                     /* faulting address is ra - 3         */
1091         mov     string_java_lang_ClassCastException,xptr
1092         jmp     asm_throw_and_handle_exception
1093
1094                 
1095 /* asm_builtin_aastore *********************************************************
1096
1097    Checks if the object can be stored in the given array and stores the
1098    address if it's possible. This function can also throw some exceptions.
1099
1100 *******************************************************************************/
1101
1102 asm_builtin_aastore:
1103         sub     $(3*8),%rsp             /* allocate stack space                   */
1104         test    %rdi,%rdi               /* if null pointer throw exception        */
1105         je      nb_aastore_null
1106
1107         movl    offarraysize(%rdi),%eax /* load size                              */
1108         cmpl    %eax,%esi               /* do bound check                         */
1109         jae     nb_aastore_bound        /* if out of bounds throw exception       */
1110
1111         shl     $3,%rsi                 /* index * 8                              */
1112         mov     %rdi,%r10
1113         add     %rsi,%r10               /* add index * 8 to arrayref              */
1114
1115         mov     %r10,(%rsp)             /* save store position                    */
1116         mov     %rdx,8(%rsp)            /* save object                            */
1117
1118         mov     %rdx,%rsi               /* object is second argument              */
1119         call    builtin_canstore        /* builtin_canstore(arrayref,object)      */
1120         test    %rax,%rax               /* if (false) throw exception             */
1121         je      nb_aastore_throw
1122
1123         mov     (%rsp),%r10             /* restore store position                 */
1124         mov     8(%rsp),%rdx            /* restore object                         */
1125         mov     %rdx,offobjarrdata(%r10)/* store objectptr in array               */
1126         add     $(3*8),%rsp             /* free stack space                       */
1127         ret
1128
1129 nb_aastore_null:
1130         add     $24,%rsp
1131         pop     xpc                    /* delete return address from stack       */
1132         sub     $3,xpc                 /* faulting address is return adress - 3  */
1133         mov     string_java_lang_NullPointerException,xptr
1134         jmp    asm_throw_and_handle_exception
1135
1136 nb_aastore_bound:
1137         mov     %rsi,%rdi               /* move index into a0                     */
1138         call    new_arrayindexoutofboundsexception
1139         add     $24,%rsp
1140         pop     %r10                    /* delete return address                  */
1141         sub     $3,%r10                 /* faulting address is return adress - 3  */
1142         jmp     asm_handle_exception
1143                 
1144 nb_aastore_throw:
1145         /*call    new_arraystoreexception*/
1146         add     $24,%rsp
1147         pop     xpc                    /* delete return address                  */
1148         sub     $3,xpc                 /* faulting address is return adress - 3  */
1149         mov     string_java_lang_ArrayStoreException,xptr
1150         jmp     asm_throw_and_handle_exception
1151
1152                 
1153 /******************* function asm_initialize_thread_stack **********************
1154 *                                                                              *
1155 * initialized a thread stack                                                   *
1156 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1157 *                                                                              *
1158 *******************************************************************************/
1159
1160 asm_initialize_thread_stack:
1161         sub     $(7*8),%rsi
1162
1163         xor     %r10,%r10
1164         mov     %r10,0*8(%rsi)
1165         mov     %r10,1*8(%rsi)
1166         mov     %r10,2*8(%rsi)
1167         mov     %r10,3*8(%rsi)
1168         mov     %r10,4*8(%rsi)
1169         mov     %r10,5*8(%rsi)
1170
1171         mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
1172         mov     %rsi,%rax               /* return restorepoint in %rax        */
1173         ret
1174
1175
1176 /******************* function asm_perform_threadswitch *************************
1177 *                                                                              *
1178 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1179 *                                                                              *
1180 *   performs a threadswitch                                                    *
1181 *                                                                              *
1182 *******************************************************************************/
1183
1184 asm_perform_threadswitch:
1185         sub     $(7*8),%rsp             /* allocate stack frame               */
1186
1187         mov     %rbx,0*8(%rsp)
1188         mov     %rbp,1*8(%rsp)
1189         mov     %r12,2*8(%rsp)
1190         mov     %r13,3*8(%rsp)
1191         mov     %r14,4*8(%rsp)
1192         mov     %r15,5*8(%rsp)
1193
1194         mov     7*8(%rsp),%rax                  /* save current return address        */
1195         mov     %rax,6*8(%rsp)
1196
1197         mov     %rsp,(%rdi)                     /* first argument **from              */
1198         mov     %rsp,(%rdx)                     /* third argument **stackTop          */
1199
1200         mov     (%rsi),%rsp                     /* load new stack pointer             */
1201
1202         mov     0*8(%rsp),%rbx
1203         mov     1*8(%rsp),%rbp
1204         mov     2*8(%rsp),%r12
1205         mov     3*8(%rsp),%r13
1206         mov     4*8(%rsp),%r14
1207         mov     5*8(%rsp),%r15
1208
1209         mov     6*8(%rsp),%rax          /* restore return address             */
1210         add     $(7*8),%rsp             /* free stack frame                   */
1211         mov     %rax,(%rsp)
1212         ret
1213                 
1214
1215 /********************* function asm_switchstackandcall *************************
1216 *                                                                              *
1217 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1218 *                                      void *p);                                       *
1219 *                                                                              *
1220 *   Switches to a new stack, calls a function and switches back.               *
1221 *       a0 (%rdi)     new stack pointer                                        *
1222 *       a1 (%rsi)     function pointer                                         *
1223 *               a2 (%rdx)     pointer to variable where stack top should be stored     *
1224 *       a3 (%rcx)     pointer to user data, is passed to the function          *
1225 *                                                                              *
1226 *******************************************************************************/
1227
1228 asm_switchstackandcall:
1229         sub     $(1*8),%rsp             /* keep stack 16-byte aligned         */
1230         sub     $16,%rdi                                /* allocate new stack                 */
1231
1232         mov     8(%rsp),%rax                    /* save return address on new stack   */
1233         mov     %rax,(%rdi)
1234         mov     %rsp,8(%rdi)                    /* save old stack pointer on new stack*/
1235         mov     %rsp,(%rdx)                             /* save old stack pointer to variable */
1236
1237         mov     %rdi,%rsp                               /* switch to new stack                */
1238
1239         mov     %rcx,%rdi                       /* pass pointer                       */
1240         call    *%rsi                                   /* and call function                  */
1241
1242         mov     (%rsp),%r10                             /* load return address                */
1243         mov     8(%rsp),%rsp                    /* switch to old stack                */
1244         add     $(1*8),%rsp             /* free stack space                   */
1245         mov     %r10,(%rsp)             /* write return adress                */
1246         ret
1247
1248
1249
1250
1251 /************************ function asm_prepare_native_stackinfo ****************************
1252 *                                                                                          *
1253 *    creates a stackfame for the begin of a native function (either builtin or not )       *
1254 *    expected stack at begin of function                                                   *
1255 *                                        ....                                              *
1256 *                   address of the jit call which invokes the native                       *
1257 *                   begin address of stack frame of the java method                        *
1258 *                   method pointer or 0 (for built ins)                                    *
1259 *                   padding for stackframesize 16*n+8                                      *
1260 *                   return address                                                         *
1261 *                                                                                          *
1262 *    at end of function:                                                                   *
1263 *                                          ...                                             *
1264 *                   address of the jit call which invokes the native                       *
1265 *                   begin address of stack frame of the java method                        *
1266 *                   method pointer or 0 (for built ins)                                    *
1267 *                   address of thread specific top of native list                          *
1268 *                   old value of thread specific head                                      *
1269 *                   padding for stackframesize 16*n+8)                                     *
1270 *                   return address                                                         *
1271 *                                                                                          *
1272 *                                        ....                                              *
1273 * This thing is less efficient than the original #define (callerside)                      *
1274 * destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
1275 ********************************************************************************************/
1276
1277
1278 asm_prepare_native_stackinfo:
1279         sub $16,%rsp  /*space for the 2 new pointers*/
1280         mov 16(%rsp),itmp2
1281         mov itmp2,(%rsp)
1282         push itmp1
1283         call builtin_asm_get_stackframeinfo
1284
1285         mov itmp1, 32(%rsp)
1286         mov (itmp1),itmp2
1287         mov itmp2,24(%rsp)
1288         mov %rsp,itmp2
1289         add $24,itmp2
1290         mov itmp2,(itmp1)
1291         pop itmp1
1292         ret
1293
1294                 
1295
1296 /************************ function asm_remove _native_stackinfo *******************************************
1297 *                                                                                                         *
1298 *    removes a stackfame for the begin of a native function (either builtin or not)                       *
1299 *    expected stack at begin of function                                                                  *
1300 *                   address of the jit call which invokes the native                                      *
1301 *                   begin address of stack frame of the java method                                       *
1302 *                   method pointer or 0 (for built ins)                                                   *
1303 *                   address thread specific top of native list                                            *
1304 *                   old value of thread specific head                                                     *
1305 *                   padding                                                                               *
1306 *                   return address                                                                        *
1307 *                                                                                                         *
1308 *    at end of function:                                                                                  *
1309 *                             ....                                                                        *
1310 *                   return adresss of the jit call which invokes the native                               *
1311 *                   padding                                                                               *
1312 *                   return address                                                                        *
1313 *                                                                                                         *
1314 *                                                                                                         *
1315 *                                                                                                         *
1316 * This thing is less efficient than the original #define (callerside), uses ITMP2,uses ITMP3,keeps ITMP1  *
1317 ***********************************************************************************************************/
1318
1319 asm_remove_native_stackinfo:
1320         mov 16(%rsp),itmp2
1321         mov 24(%rsp),itmp3
1322         mov itmp2,(itmp3)
1323         pop itmp3
1324         add $32,%rsp
1325         push itmp3
1326         ret
1327
1328
1329
1330 asm_throw_and_handle_exception:
1331         push xpc /* the pushed XPC is directly below the java frame*/
1332         push $0 
1333         push $0
1334         push $0 /*padding*/
1335         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1336         mov itmp1,%rdi
1337
1338         call new_exception
1339
1340         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1341
1342         pop xpc
1343         pop xpc
1344
1345         jmp asm_handle_exception
1346         ret /*should never be reached */
1347
1348
1349 asm_throw_and_handle_hardware_arithmetic_exception:
1350
1351         push xpc
1352         push $0 /* the pushed XPC is directly below the java frame*/
1353         push $0
1354         push $0 /*padding*/
1355         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1356
1357         mov string_java_lang_ArithmeticException_message,%rsi
1358         mov string_java_lang_ArithmeticException,%rdi
1359
1360         call new_exception_message
1361
1362         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1363         pop xpc
1364         pop xpc
1365
1366         jmp asm_handle_exception
1367         ret /*should never be reached */
1368
1369
1370 asm_getclassvalues_atomic:
1371 _crit_restart2:
1372 _crit_begin2:
1373         movl    offbaseval(a0),itmp1l
1374         movl    offdiffval(a0),itmp2l
1375         movl    offbaseval(a1),itmp3l
1376 _crit_end2:
1377         movl    itmp1l,offcast_super_baseval(a2)
1378         movl    itmp2l,offcast_super_diffval(a2)
1379         movl    itmp3l,offcast_sub_baseval(a2)
1380         ret
1381
1382         .data
1383                 
1384 asm_criticalsections:
1385 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1386         .quad   _crit_begin1
1387         .quad   _crit_end1
1388         .quad   _crit_restart1
1389         .quad   _crit_begin2
1390         .quad   _crit_end2
1391         .quad   _crit_restart2
1392 #endif
1393         .quad 0
1394
1395                 
1396 /*
1397  * These are local overrides for various environment variables in Emacs.
1398  * Please do not remove this and leave it at the end of the file, where
1399  * Emacs will automagically detect them.
1400  * ---------------------------------------------------------------------
1401  * Local variables:
1402  * mode: asm
1403  * indent-tabs-mode: t
1404  * c-basic-offset: 4
1405  * tab-width: 4
1406  * End:
1407  */