* src/vm/jit/asmpart.h [!JIT_COMPILER_VIA_SIGNAL]
[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, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include "vm/jit/x86_64/arch.h"
31 #include "vm/jit/x86_64/md-abi.h"
32 #include "vm/jit/x86_64/md-asm.h"
33
34 #include "vm/jit/abi-asm.h"
35 #include "vm/jit/methodheader.h"
36
37
38         .text
39
40
41 /* export functions ***********************************************************/
42
43         .globl asm_vm_call_method
44         .globl asm_vm_call_method_int
45         .globl asm_vm_call_method_long
46         .globl asm_vm_call_method_float
47         .globl asm_vm_call_method_double
48         .globl asm_vm_call_method_exception_handler
49         .globl asm_vm_call_method_end
50
51         .globl asm_handle_exception
52         .globl asm_handle_nat_exception
53
54         .globl asm_abstractmethoderror
55
56         .globl asm_builtin_f2i
57         .globl asm_builtin_f2l
58         .globl asm_builtin_d2i
59         .globl asm_builtin_d2l
60
61         .globl asm_compare_and_swap
62         .globl asm_memory_barrier
63
64
65 /********************* function asm_calljavafunction ***************************
66 *                                                                              *
67 *   This function calls a Java-method (which possibly needs compilation)       *
68 *   with up to 4 address parameters.                                           *
69 *                                                                              *
70 *   This functions calls the JIT-compiler which eventually translates the      *
71 *   method into machine code.                                                  *
72 *                                                                              *
73 *   C-prototype:                                                               *
74 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
75 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
76 *                                                                              *
77 *******************************************************************************/
78
79         .align  8
80
81         .quad   0                           /* catch type all                     */
82         .quad   0                           /* handler pc                         */
83         .quad   0                           /* end pc                             */
84         .quad   0                           /* start pc                           */
85         .long   1                           /* extable size                       */
86         .long   0                           /* ALIGNMENT PADDING                  */
87         .quad   0                           /* line number table  start           */
88         .quad   0                           /* line number table  size            */
89         .long   0                           /* ALIGNMENT PADDING                  */
90         .long   0                           /* fltsave                            */
91         .long   0                           /* intsave                            */
92         .long   0                           /* isleaf                             */
93         .long   0                           /* IsSync                             */
94         .long   0                           /* frame size                         */
95         .quad   0                           /* codeinfo pointer                   */
96
97 asm_vm_call_method:
98 asm_vm_call_method_int:
99 asm_vm_call_method_long:
100 asm_vm_call_method_float:
101 asm_vm_call_method_double:
102         sub     $(7*8),sp                   /* keep stack 16-byte aligned         */
103         mov     %rbx,0*8(sp)                /* %rbx is not a callee saved in cacao*/
104         mov     s0,1*8(sp)
105         mov     s1,2*8(sp)
106         mov     s2,3*8(sp)
107         mov     s3,4*8(sp)
108         mov     s4,5*8(sp)
109
110         mov     a0,6*8(sp)                  /* store method PV                    */
111
112         mov     sp,s0                       /* save stack pointer                 */
113
114         mov     a1,t0                       /* address of data structure          */
115         mov     a2,itmp1                    /* number of stack arguments          */
116
117         mov     0*8(t0),a0
118         mov     1*8(t0),a1
119         mov     2*8(t0),a2
120         mov     3*8(t0),a3
121         mov     4*8(t0),a4
122         mov     5*8(t0),a5
123
124         movq    6*8(t0),fa0
125         movq    7*8(t0),fa1
126         movq    8*8(t0),fa2
127         movq    9*8(t0),fa3
128         movq    10*8(t0),fa4
129         movq    11*8(t0),fa5
130         movq    12*8(t0),fa6
131         movq    13*8(t0),fa7
132
133         cmp     $0,itmp1l
134         je      L_asm_vm_call_method_stack_copy_done
135
136         mov     itmp1,itmp2
137         add     $1,itmp2                    /* keep stack 16-byte aligned         */
138         and     $0xfffffffffffffffe,itmp2
139         shl     $3,itmp2                    /* calculate stack size               */
140         sub     itmp2,sp                    /* create stack frame                 */
141         mov     sp,itmp2                    /* temporary stack pointer            */
142
143 L_asm_vm_call_method_stack_copy_loop:
144         mov     14*8(t0),itmp3              /* load argument                      */
145         mov     itmp3,0(itmp2)              /* store argument on stack            */
146
147         sub     $1,itmp1l                   /* subtract 1 argument                */
148         add     $8,t0                       /* set address of next argument       */
149         add     $8,itmp2                    /* increase SP                        */
150
151         cmp     $0,itmp1l
152         jg      L_asm_vm_call_method_stack_copy_loop
153
154 L_asm_vm_call_method_stack_copy_done:
155         lea     (6*8-256)(s0),mptr          /* We subtract 256 to force the next  */
156                                             /* move instruction to have a 32-bit  */
157                                             /* offset.                            */
158
159         mov     (0*8+256)(mptr),itmp3       /* load PV                            */
160         call    *itmp3
161
162         mov     s0,sp                       /* restore SP                         */
163
164 L_asm_vm_call_method_return:
165         mov     0*8(sp),%rbx                /* restore callee saved registers     */
166         mov     1*8(sp),s0
167         mov     2*8(sp),s1
168         mov     3*8(sp),s2
169         mov     4*8(sp),s3
170         mov     5*8(sp),s4
171         add     $(7*8),sp                   /* free stack space                   */
172         ret
173                 
174 asm_vm_call_method_exception_handler:
175         mov     xptr,a0                     /* pass exception pointer             */
176         call    builtin_throw_exception@PLT
177         jmp     L_asm_vm_call_method_return
178
179 asm_vm_call_method_end:
180         nop
181
182
183 /* asm_handle_exception ********************************************************
184 *                                                                              *
185 *   This function handles an exception. It does not use the usual calling      *
186 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
187 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
188 *   the local exception table for a handler. If no one is found, it unwinds    *
189 *   stacks and continues searching the callers.                                *
190 *                                                                              *
191 *******************************************************************************/
192
193 asm_handle_nat_exception:
194         add     $8,sp                       /* clear return address of native stub*/
195                 
196 asm_handle_exception:
197 L_asm_handle_exception:                 /* required for PIC code              */
198         sub     $((ARG_CNT+TMP_CNT)*8),sp   /* create maybe-leaf stackframe       */
199
200         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
201         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
202
203         mov     $((ARG_CNT+TMP_CNT)*8),a3   /* prepare a3 for handle_exception    */
204         mov     $1,t0                       /* set maybe-leaf flag                */
205
206 L_asm_handle_exception_stack_loop:
207         sub     $(6*8),sp
208         mov     xptr,0*8(sp)                /* save exception pointer             */
209         mov     xpc,1*8(sp)                 /* save exception pc                  */
210         add     sp,a3                       /* calculate Java sp into a3...       */
211         add     $(6*8),a3
212         mov     a3,3*8(sp)                  /* ...and save it                     */
213         mov     t0,4*8(sp)                  /* save maybe-leaf flag               */
214
215         mov     xpc,a0                      /* exception pc                       */
216         call    codegen_get_pv_from_pc@PLT
217         mov     v0,2*8(sp)                  /* save data segment pointer          */
218         
219         mov     0*8(sp),a0                  /* pass exception pointer             */
220         mov     1*8(sp),a1                  /* pass exception pc                  */
221         mov     v0,a2                       /* pass data segment pointer          */
222         mov     3*8(sp),a3                  /* pass Java stack pointer            */
223         call    exceptions_handle_exception@PLT
224
225         test    v0,v0
226         jz      L_asm_handle_exception_not_catched
227
228         mov     v0,xpc                      /* move handlerpc into xpc            */
229         mov     0*8(sp),xptr                /* restore exception pointer          */
230         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
231         add     $(6*8),sp                   /* free stack frame                   */
232
233         test    t0,t0                       /* test for maybe-leaf flag           */
234         jz      L_asm_handle_exception_no_leaf
235
236         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
237         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
238
239         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
240
241 L_asm_handle_exception_no_leaf:
242         jmp     *xpc                        /* jump to the handler                */
243
244 L_asm_handle_exception_not_catched:
245         mov     0*8(sp),xptr                /* restore exception pointer          */
246         mov     2*8(sp),itmp3               /* restore data segment pointer       */
247         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
248         add     $(6*8),sp
249
250         test    t0,t0
251         jz      L_asm_handle_exception_no_leaf_stack
252
253         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
254         xor     t0,t0                       /* clear the isleaf flags             */
255
256 L_asm_handle_exception_no_leaf_stack:
257         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
258         add     sp,itmp2                    /* pointer to save area               */
259         
260         mov     IntSave(itmp3),a0l          /* a0l = saved int register count     */
261         test    a0l,a0l
262         je      noint
263         
264         cmp     $1,a0l
265         je      int1
266         cmp     $2,a0l
267         je      int2
268         cmp     $3,a0l
269         je      int3
270         cmp     $4,a0l
271         je      int4
272         
273         mov     -5*8(itmp2),s0
274 int4:   
275         mov     -4*8(itmp2),s1
276 int3:   
277         mov     -3*8(itmp2),s2
278 int2:   
279         mov     -2*8(itmp2),s3
280 int1:   
281         mov     -1*8(itmp2),s4
282
283         shl     $3,a0l                      /* multiply by 8 bytes                */
284         sub     a0,itmp2
285                 
286 noint:
287 #if 0
288         mov     FltSave(itmp3),a0l          /* a0l = saved flt register count     */
289         test    a0l,a0l
290         je      noflt
291         
292         cmpl    $1,a0l
293         je      flt1
294         cmpl    $2,a0l
295         je      flt2
296         cmpl    $3,a0l
297         je      flt3
298         cmpl    $4,a0l
299         je      flt4
300
301         movq    -5*8(itmp2),%xmm11
302 flt4:   
303         movq    -4*8(itmp2),%xmm12
304 flt3:   
305         movq    -3*8(itmp2),%xmm13
306 flt2:   
307         movq    -2*8(itmp2),%xmm14
308 flt1:   
309         movq    -1*8(itmp2),%xmm15
310                 
311 noflt:
312 #endif
313         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
314         add     itmp2,sp                    /* unwind stack                       */
315
316                                             /* exception pointer is still set     */
317         pop     xpc                         /* the new xpc is return address      */
318         sub     $3,xpc                      /* subtract 3 bytes for call          */
319
320         xor     a3,a3                       /* prepare a3 for handle_exception    */
321         
322         jmp             L_asm_handle_exception_stack_loop
323
324
325 /* asm_abstractmethoderror *****************************************************
326
327    Creates and throws an AbstractMethodError.
328
329 *******************************************************************************/
330
331 asm_abstractmethoderror:
332         mov     sp,a0                       /* pass java sp                       */
333         add     $1*8,a0
334         mov     0*8(sp),a1                  /* pass exception address             */
335         sub     $3,a1
336         call    exceptions_asm_new_abstractmethoderror@PLT
337                                             /* exception pointer is return value  */
338         pop     xpc                         /* get exception address              */
339         sub     $3,xpc                      /* exception address is ra - 3        */
340         jmp     L_asm_handle_exception
341
342
343 /* asm_builtin_x2x *************************************************************
344 *                                                                              *
345 *   Wrapper functions for float to int corner cases                            *
346 *                                                                              *
347 *******************************************************************************/
348
349 asm_builtin_f2i:
350         sub     $(ARG_CNT*8),sp
351         
352         SAVE_ARGUMENT_REGISTERS(0)
353         
354         movq    ftmp1,fa0
355         call    builtin_f2i@PLT
356         
357         RESTORE_ARGUMENT_REGISTERS(0)
358         
359         add     $(ARG_CNT*8),sp
360         ret
361
362
363 asm_builtin_f2l:
364         sub     $(ARG_CNT*8),sp
365         
366         SAVE_ARGUMENT_REGISTERS(0)
367         
368         movq    ftmp1,fa0
369         call    builtin_f2l@PLT
370         
371         RESTORE_ARGUMENT_REGISTERS(0)
372         
373         add     $(ARG_CNT*8),sp
374         ret
375
376
377 asm_builtin_d2i:
378         sub     $(ARG_CNT*8),sp
379         
380         SAVE_ARGUMENT_REGISTERS(0)
381         
382         movq    ftmp1,fa0
383         call    builtin_d2i@PLT
384         
385         RESTORE_ARGUMENT_REGISTERS(0)
386         
387         add     $(ARG_CNT*8),sp
388         ret
389
390
391 asm_builtin_d2l:
392         sub     $(ARG_CNT*8),sp
393         
394         SAVE_ARGUMENT_REGISTERS(0)
395         
396         movq    ftmp1,fa0
397         call    builtin_d2l@PLT
398         
399         RESTORE_ARGUMENT_REGISTERS(0)
400         
401         add     $(ARG_CNT*8),sp
402         ret
403
404
405 /* asm_compare_and_swap ********************************************************
406
407    Does an atomic compare and swap.  Required for the lock
408    implementation.
409
410 *******************************************************************************/
411
412 asm_compare_and_swap:
413         mov     a1,v0                       /* v0 is %rax                         */
414         lock cmpxchg a2,(a0)
415         ret
416
417
418 /* asm_memory_barrier **********************************************************
419
420    A memory barrier for the Java Memory Model.
421
422 *******************************************************************************/
423
424 asm_memory_barrier:
425         mfence
426         ret
427
428
429 /* disable exec-stacks ********************************************************/
430
431 #if defined(__linux__) && defined(__ELF__)
432         .section .note.GNU-stack,"",%progbits
433 #endif
434
435
436 /*
437  * These are local overrides for various environment variables in Emacs.
438  * Please do not remove this and leave it at the end of the file, where
439  * Emacs will automagically detect them.
440  * ---------------------------------------------------------------------
441  * Local variables:
442  * mode: asm
443  * indent-tabs-mode: t
444  * c-basic-offset: 4
445  * tab-width: 4
446  * End:
447  * vim:noexpandtab:sw=4:ts=4:
448  */