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