* src/vm/utf8.c (utf_java_lang_AbstractMethodError): Added.
[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 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    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Christian Thalinger
30
31    Changes: Edwin Steiner
32
33    $Id: asmpart.S 5053 2006-06-28 19:11:20Z twisti $
34
35 */
36
37
38 #include "config.h"
39
40 #include "vm/jit/x86_64/arch.h"
41 #include "vm/jit/x86_64/md-abi.h"
42 #include "vm/jit/x86_64/md-asm.h"
43 #include "vm/jit/x86_64/offsets.h"
44
45 #include "vm/jit/abi-asm.h"
46 #include "vm/jit/methodheader.h"
47
48
49         .text
50
51
52 /* export functions ***********************************************************/
53
54         .globl asm_vm_call_method
55         .globl asm_vm_call_method_int
56         .globl asm_vm_call_method_long
57         .globl asm_vm_call_method_float
58         .globl asm_vm_call_method_double
59         .globl asm_vm_call_method_exception_handler
60
61         .globl asm_call_jit_compiler
62         .globl asm_handle_exception
63         .globl asm_handle_nat_exception
64
65         .globl asm_abstractmethoderror
66
67         .globl asm_wrapper_patcher
68
69         .globl asm_replacement_out
70         .globl asm_replacement_in
71
72         .globl asm_builtin_f2i
73         .globl asm_builtin_f2l
74         .globl asm_builtin_d2i
75         .globl asm_builtin_d2l
76
77         .globl asm_criticalsections
78         .globl asm_getclassvalues_atomic
79
80
81 /********************* function asm_calljavafunction ***************************
82 *                                                                              *
83 *   This function calls a Java-method (which possibly needs compilation)       *
84 *   with up to 4 address parameters.                                           *
85 *                                                                              *
86 *   This functions calls the JIT-compiler which eventually translates the      *
87 *   method into machine code.                                                  *
88 *                                                                              *
89 *   C-prototype:                                                               *
90 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
91 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
92 *                                                                              *
93 *******************************************************************************/
94
95         .align  8
96
97         .quad   0                           /* catch type all                     */
98         .quad   0                           /* handler pc                         */
99         .quad   0                           /* end pc                             */
100         .quad   0                           /* start pc                           */
101         .long   1                           /* extable size                       */
102         .long   0                           /* ALIGNMENT PADDING                  */
103         .quad   0                           /* line number table  start           */
104         .quad   0                           /* line number table  size            */
105         .long   0                           /* ALIGNMENT PADDING                  */
106         .long   0                           /* fltsave                            */
107         .long   0                           /* intsave                            */
108         .long   0                           /* isleaf                             */
109         .long   0                           /* IsSync                             */
110         .long   0                           /* frame size                         */
111         .quad   0                           /* codeinfo pointer                   */
112
113 asm_vm_call_method:
114 asm_vm_call_method_int:
115 asm_vm_call_method_long:
116 asm_vm_call_method_float:
117 asm_vm_call_method_double:
118         sub     $(7*8),sp                   /* keep stack 16-byte aligned         */
119         mov     %rbx,0*8(sp)                /* %rbx is not a callee saved in cacao*/
120         mov     s0,1*8(sp)
121         mov     s1,2*8(sp)
122         mov     s2,3*8(sp)
123         mov     s3,4*8(sp)
124         mov     s4,5*8(sp)
125
126         mov     a0,itmp1                    /* move method pointer for compiler   */
127         xor     %rbp,%rbp                   /* set argument stack frame to zero   */
128
129         test    a1,a1                       /* maybe we have no args...           */
130         jle     L_copy_done
131
132         mov     a1,itmp3                    /* arg count                          */
133         mov     a2,itmp2                    /* pointer to arg block               */
134
135         mov     itmp2,%r14                  /* save argument block pointer        */
136         mov     itmp3,%r15                  /* save argument count                */
137
138         sub     $sizevmarg,itmp2            /* initialize pointer (smaller code)  */
139         add     $1,itmp3                    /* initialize argument count          */
140         xor     %r12,%r12                   /* initialize integer argument counter*/
141         xor     %r13,%r13                   /* initialize float argument counter  */
142
143 L_register_copy:
144         add     $sizevmarg,itmp2            /* goto next argument block           */
145         dec     itmp3                       /* argument count - 1                 */
146         jz      L_register_copy_done
147         andb    $0x02,offvmargtype(itmp2)   /* is this a float/double type?       */
148         jnz     L_register_handle_float     /* yes, handle it                     */
149
150         cmp     $INT_ARG_CNT,%r12           /* are we out of integer argument     */
151         je      L_register_copy             /* register? yes, next loop           */
152
153         lea     jumptable_integer(%rip),%rbp
154         mov     0(%rbp,%r12,8),%rbx
155         inc     %r12                      /* integer argument counter + 1         */
156         jmp     *%rbx
157
158 L_register_handle_float:
159         cmp     $FLT_ARG_CNT,%r13         /* are we out of float argument         */
160         je      L_register_copy           /* register? yes, next loop             */
161
162         lea     jumptable_float(%rip),%rbp
163         mov     0(%rbp,%r13,8),%rbx
164         inc     %r13                      /* float argument counter + 1           */
165         jmp     *%rbx
166         
167 L_register_copy_done:
168         mov     %r15,%rbp                 /* calculate remaining arguments        */
169         sub     %r12,%rbp                 /* - integer arguments in registers     */
170         sub     %r13,%rbp                 /* - float arguments in registers       */
171         jle     L_copy_done               /* are all assigned to registers?       */
172
173         and     $0xfffffffffffffffe,%rbp  /* keep stack 16-byte aligned           */
174         shl     $3,%rbp                   /* calculate stack size                 */
175         sub     %rbp,sp                   /* stack frame for arguments            */
176         mov     sp,%rbx                   /* use %rbx as temp sp                  */
177
178         sub     $sizevmarg,%r14           /* initialize pointer (smaller code)    */
179         add     $1,%r15                   /* initialize argument count            */
180                 
181 L_stack_copy_loop:
182         add     $sizevmarg,%r14           /* goto next argument block             */
183         dec     %r15                      /* are there any arguments left?        */
184         jz      L_copy_done               /* no test needed after dec             */
185
186         andb    $0x02,offvmargtype(%r14)    /* is this a float/double type?       */
187         jnz     L_stack_handle_float
188         dec     %r12                        /* arguments assigned to registers    */
189         jge     L_stack_copy_loop
190         jmp     L_stack_copy
191
192 L_stack_handle_float:
193         dec     %r13                        /* arguments assigned to registers    */
194         jge     L_stack_copy_loop
195
196 L_stack_copy:
197         mov     offvmargdata(%r14),itmp3    /* copy s8 argument onto stack        */
198         mov     itmp3,0(%rbx)
199         add     $8,%rbx                     /* increase sp to next argument       */
200         jmp     L_stack_copy_loop
201
202 L_copy_done:
203                                             /* itmp1 still contains method pointer*/
204         lea     L_asm_call_jit_compiler(%rip),mptr
205         mov     sp,itmp3                    /* calculate the old stack pointer    */
206         add     bp,itmp3
207         mov     mptr,6*8(itmp3)
208         lea     (6*8-256)(itmp3),mptr       /* We subtract 256 to force the next  */
209                                             /* move instruction to have a 32-bit  */
210                                             /* offset.                            */
211
212         mov     (0*8+256)(mptr),itmp3       /* method call as in Java             */
213         call    *itmp3                      /* call JIT compiler                  */
214
215         add     bp,sp                       /* remove argument stack frame if any */
216
217 L_asm_vm_call_method_return:
218         mov     0*8(sp),%rbx                /* restore callee saved registers     */
219         mov     1*8(sp),s0
220         mov     2*8(sp),s1
221         mov     3*8(sp),s2
222         mov     4*8(sp),s3
223         mov     5*8(sp),s4
224         add     $(7*8),sp                   /* free stack space                   */
225         ret
226                 
227 asm_vm_call_method_exception_handler:
228         mov     xptr,a0                     /* pass exception pointer             */
229         call    builtin_throw_exception@PLT
230         jmp     L_asm_vm_call_method_return
231
232
233 jumptable_integer:
234         .quad   handle_a0
235         .quad   handle_a1
236         .quad   handle_a2
237         .quad   handle_a3
238         .quad   handle_a4
239         .quad   handle_a5
240
241 handle_a0:
242         mov     offvmargdata(itmp2),a0
243         jmp     L_register_copy
244 handle_a1:
245         mov     offvmargdata(itmp2),a1
246         jmp     L_register_copy
247 handle_a2:
248         mov     offvmargdata(itmp2),a2
249         jmp     L_register_copy
250 handle_a3:
251         mov     offvmargdata(itmp2),a3
252         jmp     L_register_copy
253 handle_a4:
254         mov     offvmargdata(itmp2),a4
255         jmp     L_register_copy
256 handle_a5:
257         mov     offvmargdata(itmp2),a5
258         jmp     L_register_copy
259
260
261 jumptable_float:
262         .quad   handle_fa0
263         .quad   handle_fa1
264         .quad   handle_fa2
265         .quad   handle_fa3
266         .quad   handle_fa4
267         .quad   handle_fa5
268         .quad   handle_fa6
269         .quad   handle_fa7
270
271 handle_fa0:
272         movq    offvmargdata(itmp2),fa0
273         jmp     L_register_copy
274 handle_fa1:
275         movq    offvmargdata(itmp2),fa1
276         jmp     L_register_copy
277 handle_fa2:
278         movq    offvmargdata(itmp2),fa2
279         jmp     L_register_copy
280 handle_fa3:
281         movq    offvmargdata(itmp2),fa3
282         jmp     L_register_copy
283 handle_fa4:
284         movq    offvmargdata(itmp2),fa4
285         jmp     L_register_copy
286 handle_fa5:
287         movq    offvmargdata(itmp2),fa5
288         jmp     L_register_copy
289 handle_fa6:
290         movq    offvmargdata(itmp2),fa6
291         jmp     L_register_copy
292 handle_fa7:
293         movq    offvmargdata(itmp2),fa7
294         jmp     L_register_copy
295
296
297 /****************** function asm_call_jit_compiler *****************************
298 *                                                                              *
299 *   invokes the compiler for untranslated JavaVM methods.                      *
300 *                                                                              *
301 *   Register R0 contains a pointer to the method info structure (prepared      *
302 *   by createcompilerstub). Using the return address in R26 and the            *
303 *   offset in the LDA instruction or using the value in methodptr R28 the      *
304 *   patching address for storing the method address can be computed:           *
305 *                                                                              *
306 *   method address was either loaded using                                     *
307 *                                                                              *
308 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
309 *   i386_call_reg(REG_ITMP2)                                                   *
310 *                                                                              *
311 *   or                                                                         *
312 *                                                                              *
313 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
314 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
315 *   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
316 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
317 *   i386_call_reg(REG_ITMP1)                                                   *
318 *                                                                              *
319 *   in the static case the method pointer can be computed using the            *
320 *   return address and the lda function following the jmp instruction          *
321 *                                                                              *
322 *******************************************************************************/
323
324 asm_call_jit_compiler:
325 L_asm_call_jit_compiler:                /* required for PIC code              */
326         sub     $(ARG_CNT+1)*8,sp           /* +1: keep stack 16-byte aligned     */
327
328         SAVE_ARGUMENT_REGISTERS(0)
329
330         mov     itmp1,a0                    /* pass methodinfo pointer            */
331         mov     mptr,a1                     /* pass method pointer                */
332         mov     sp,a2                       /* pass java sp                       */
333         add     $(1+ARG_CNT+1)*8,a2
334         mov     (ARG_CNT+1)*8(sp),a3        /* pass ra to java function           */
335         call    jit_asm_compile@PLT
336
337         RESTORE_ARGUMENT_REGISTERS(0)
338
339         add     $(ARG_CNT+1)*8,sp           /* remove stack frame                 */
340
341         test    v0,v0                       /* check for exception                */
342         je      L_asm_call_jit_compiler_exception
343
344         jmp     *v0                         /* ...and now call the new method     */
345
346 L_asm_call_jit_compiler_exception:
347 #if defined(ENABLE_THREADS)
348         call    builtin_asm_get_exceptionptrptr@PLT
349         mov     v0,itmp2                    /* v0 == xptr                         */
350 #else
351         lea     _no_threads_exceptionptr(%rip),itmp2
352 #endif
353         mov     (itmp2),xptr                /* get the exception pointer          */
354         movl    $0,(itmp2)                  /* clear exception pointer            */
355
356         pop     xpc                         /* delete return address              */
357         sub     $5,xpc                      /* faulting address is ra - 5         */
358         jmp     L_asm_handle_exception
359
360
361 /* asm_handle_exception ********************************************************
362 *                                                                              *
363 *   This function handles an exception. It does not use the usual calling      *
364 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
365 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
366 *   the local exception table for a handler. If no one is found, it unwinds    *
367 *   stacks and continues searching the callers.                                *
368 *                                                                              *
369 *******************************************************************************/
370
371 asm_handle_nat_exception:
372         add     $8,sp                       /* clear return address of native stub*/
373                 
374 asm_handle_exception:
375 L_asm_handle_exception:                 /* required for PIC code              */
376         sub     $((ARG_CNT+TMP_CNT)*8),sp   /* create maybe-leaf stackframe       */
377
378         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
379         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
380
381         mov     $((ARG_CNT+TMP_CNT)*8),a3   /* prepare a3 for handle_exception    */
382         mov     $1,t0                       /* set maybe-leaf flag                */
383
384 L_asm_handle_exception_stack_loop:
385         sub     $(6*8),sp
386         mov     xptr,0*8(sp)                /* save exception pointer             */
387         mov     xpc,1*8(sp)                 /* save exception pc                  */
388         add     sp,a3                       /* calculate Java sp into a3...       */
389         add     $(6*8),a3
390         mov     a3,3*8(sp)                  /* ...and save it                     */
391         mov     t0,4*8(sp)                  /* save maybe-leaf flag               */
392
393         mov     xpc,a0                      /* exception pc                       */
394         call    codegen_findmethod@PLT
395         mov     v0,2*8(sp)                  /* save data segment pointer          */
396         
397         mov     0*8(sp),a0                  /* pass exception pointer             */
398         mov     1*8(sp),a1                  /* pass exception pc                  */
399         mov     v0,a2                       /* pass data segment pointer          */
400         mov     3*8(sp),a3                  /* pass Java stack pointer            */
401         call    exceptions_handle_exception@PLT
402
403         test    v0,v0
404         jz      L_asm_handle_exception_not_catched
405
406         mov     v0,xpc                      /* move handlerpc into xpc            */
407         mov     0*8(sp),xptr                /* restore exception pointer          */
408         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
409         add     $(6*8),sp                   /* free stack frame                   */
410
411         test    t0,t0                       /* test for maybe-leaf flag           */
412         jz      L_asm_handle_exception_no_leaf
413
414         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
415         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
416
417         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
418
419 L_asm_handle_exception_no_leaf:
420         jmp     *xpc                        /* jump to the handler                */
421
422 L_asm_handle_exception_not_catched:
423         mov     0*8(sp),xptr                /* restore exception pointer          */
424         mov     2*8(sp),itmp3               /* restore data segment pointer       */
425         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
426         add     $(6*8),sp
427
428         test    t0,t0
429         jz      L_asm_handle_exception_no_leaf_stack
430
431         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
432         xor     t0,t0                       /* clear the isleaf flags             */
433
434 L_asm_handle_exception_no_leaf_stack:
435         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
436         add     sp,itmp2                    /* pointer to save area               */
437         
438         mov     IntSave(itmp3),a0l          /* a0l = saved int register count     */
439         test    a0l,a0l
440         je      noint
441         
442         cmp     $1,a0l
443         je      int1
444         cmp     $2,a0l
445         je      int2
446         cmp     $3,a0l
447         je      int3
448         cmp     $4,a0l
449         je      int4
450         
451         mov     -5*8(itmp2),s0
452 int4:   
453         mov     -4*8(itmp2),s1
454 int3:   
455         mov     -3*8(itmp2),s2
456 int2:   
457         mov     -2*8(itmp2),s3
458 int1:   
459         mov     -1*8(itmp2),s4
460
461         shl     $3,a0l                      /* multiply by 8 bytes                */
462         sub     a0,itmp2
463                 
464 noint:
465 #if 0
466         mov     FltSave(itmp3),a0l          /* a0l = saved flt register count     */
467         test    a0l,a0l
468         je      noflt
469         
470         cmpl    $1,a0l
471         je      flt1
472         cmpl    $2,a0l
473         je      flt2
474         cmpl    $3,a0l
475         je      flt3
476         cmpl    $4,a0l
477         je      flt4
478
479         movq    -5*8(itmp2),%xmm11
480 flt4:   
481         movq    -4*8(itmp2),%xmm12
482 flt3:   
483         movq    -3*8(itmp2),%xmm13
484 flt2:   
485         movq    -2*8(itmp2),%xmm14
486 flt1:   
487         movq    -1*8(itmp2),%xmm15
488                 
489 noflt:
490 #endif
491         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
492         add     itmp2,sp                    /* unwind stack                       */
493
494                                             /* exception pointer is still set     */
495         pop     xpc                         /* the new xpc is return address      */
496         sub     $3,xpc                      /* subtract 3 bytes for call          */
497
498         xor     a3,a3                       /* prepare a3 for handle_exception    */
499         
500         jmp             L_asm_handle_exception_stack_loop
501
502
503 /* asm_abstractmethoderror *****************************************************
504
505    Creates and throws an AbstractMethodError.
506
507 *******************************************************************************/
508
509 asm_abstractmethoderror:
510         call    exceptions_new_abstractmethoderror@PLT
511                                             /* exception pointer is return value  */
512         pop     xpc                         /* get exception address              */
513         sub     $5,xpc                      /* exception address is ra - 5        */
514         jmp     L_asm_handle_exception
515
516
517 /* asm_wrapper_patcher *********************************************************
518
519    XXX
520
521    Stack layout:
522      40   return address
523      32   pointer to virtual java_objectheader
524      24   machine code (which is patched back later)
525      16   unresolved class/method/field reference
526       8   data segment displacement from load instructions
527       0   pointer to patcher function
528      -8   bp
529
530 *******************************************************************************/
531
532 asm_wrapper_patcher:
533         push    bp                          /* save base pointer                  */
534         mov     sp,bp                       /* move actual sp to bp               */
535         sub     $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
536         and     $0xfffffffffffffff0,sp      /* align sp to 16-byte (this is for   */
537                                             /* leaf functions)                    */
538
539         SAVE_ARGUMENT_REGISTERS(3)
540         SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
541
542         mov     itmp1,0*8(sp)               /* save itmp1 and itmp2               */
543         mov     itmp2,1*8(sp)               /* can be used by some instructions   */
544
545         mov     sp,a0                       /* create stackframe info             */
546         add     $((3+ARG_CNT+TMP_CNT)*8),a0
547         xor     a1,a1                       /* if pv is NULL, use findmethod      */
548         mov     bp,a2                       /* pass java sp                       */
549         add     $((6+1)*8),a2
550         mov     ((5+1)*8)(bp),a3            /* pass ra to java function           */
551         mov     a3,a4                       /* xpc is equal to ra                 */
552         call    stacktrace_create_extern_stackframeinfo@PLT
553
554         mov     bp,a0                       /* pass stack pointer                 */
555         add     $((1+1)*8),a0               /* skip function pointer              */
556         mov     1*8(bp),itmp3               /* get function pointer               */
557         call    *itmp3                      /* call the patcher function          */
558         mov     v0,2*8(sp)                  /* save return value                  */
559
560         mov     sp,a0                       /* remove stackframe info             */
561         add     $((3+ARG_CNT+TMP_CNT)*8),a0
562         call    stacktrace_remove_stackframeinfo@PLT
563
564         RESTORE_ARGUMENT_REGISTERS(3)
565         RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
566
567         mov     0*8(sp),itmp1               /* restore itmp1 and itmp2            */
568         mov     1*8(sp),itmp2               /* can be used by some instructions   */
569         mov     2*8(sp),itmp3               /* restore return value               */
570
571         mov     bp,sp                       /* restore original sp                */
572         pop     bp                          /* restore bp                         */
573         add     $(5*8),sp                   /* remove patcher stackframe, keep ra */
574
575         test    itmp3,itmp3                 /* exception thrown?                  */
576         jz      L_asm_wrapper_patcher_exception
577         ret                                 /* call new patched code              */
578
579 L_asm_wrapper_patcher_exception:
580 #if defined(ENABLE_THREADS)
581         call    builtin_asm_get_exceptionptrptr@PLT
582         mov     v0,itmp2                    /* v0 == xptr                         */
583 #else
584         mov     _no_threads_exceptionptr,itmp2
585 #endif
586         mov     (itmp2),xptr                /* get the exception pointer          */
587         movl    $0,(itmp2)                  /* clear exception pointer            */
588
589         pop     xpc                         /* get and remove return address      */
590         jmp     L_asm_handle_exception
591
592
593 /* asm_replacement_out *********************************************************
594
595    This code is jumped to from the replacement-out stubs that are executed
596    when a thread reaches an activated replacement point.
597
598    The purpose of asm_replacement_out is to read out the parts of the
599    execution state that cannot be accessed from C code, store this state,
600    and then call the C function replace_me.
601
602    Stack layout:
603       8                 start of stack inside method to replace
604       0   rplpoint *    info on the replacement point that was reached
605
606 *******************************************************************************/
607
608 /* some room to accomodate changes of the stack frame size during replacement */
609         /* XXX we should find a cleaner solution here */
610 #define REPLACEMENT_ROOM  512
611
612 asm_replacement_out:
613     /* create stack frame */
614         sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
615
616         /* save registers in execution state */
617         mov     %rax,(RAX*8+offes_intregs)(sp)
618         mov     %rbx,(RBX*8+offes_intregs)(sp)
619         mov     %rcx,(RCX*8+offes_intregs)(sp)
620         mov     %rdx,(RDX*8+offes_intregs)(sp)
621         mov     %rsi,(RSI*8+offes_intregs)(sp)
622         mov     %rdi,(RDI*8+offes_intregs)(sp)
623         mov     %rbp,(RBP*8+offes_intregs)(sp)
624         movq    $0  ,(RSP*8+offes_intregs)(sp) /* not used */
625         mov     %r8 ,(R8 *8+offes_intregs)(sp)
626         mov     %r9 ,(R9 *8+offes_intregs)(sp)
627         mov     %r10,(R10*8+offes_intregs)(sp)
628         mov     %r11,(R11*8+offes_intregs)(sp)
629         mov     %r12,(R12*8+offes_intregs)(sp)
630         mov     %r13,(R13*8+offes_intregs)(sp)
631         mov     %r14,(R14*8+offes_intregs)(sp)
632         mov     %r15,(R15*8+offes_intregs)(sp)
633
634         movq    %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
635         movq    %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
636         movq    %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
637         movq    %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
638         movq    %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
639         movq    %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
640         movq    %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
641         movq    %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
642         movq    %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
643         movq    %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
644         movq    %xmm10,(XMM10*8+offes_fltregs)(sp)
645         movq    %xmm11,(XMM11*8+offes_fltregs)(sp)
646         movq    %xmm12,(XMM12*8+offes_fltregs)(sp)
647         movq    %xmm13,(XMM13*8+offes_fltregs)(sp)
648         movq    %xmm14,(XMM14*8+offes_fltregs)(sp)
649         movq    %xmm15,(XMM15*8+offes_fltregs)(sp)
650
651         /* calculate sp of method */
652         mov     sp,itmp1
653         add     $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
654         mov     itmp1,(offes_sp)(sp)
655
656         /* pv must be looked up via AVL tree */
657         movq    $0,(offes_pv)(sp)
658
659         /* call replace_me */
660         mov     -8(itmp1),a0                /* rplpoint *                         */
661     mov     sp,a1                       /* arg1: execution state              */
662     call    replace_me@PLT              /* call C function replace_me         */
663     call    abort@PLT                   /* NEVER REACHED                      */
664
665 /* asm_replacement_in **********************************************************
666
667    This code writes the given execution state and jumps to the replacement
668    code.
669
670    This function never returns!
671
672    C prototype:
673       void asm_replacement_in(executionstate *es);
674
675 *******************************************************************************/
676
677 asm_replacement_in:
678         mov     a0,%rbp                     /* executionstate *es                 */
679
680         /* set new sp */
681         mov     (offes_sp)(%rbp),%rsp
682         
683         /* store address of new code */
684         push    (offes_pc)(%rbp)
685         
686         /* copy registers from execution state */
687         movq    (XMM0 *8+offes_fltregs)(%rbp),%xmm0
688         movq    (XMM1 *8+offes_fltregs)(%rbp),%xmm1
689         movq    (XMM2 *8+offes_fltregs)(%rbp),%xmm2
690         movq    (XMM3 *8+offes_fltregs)(%rbp),%xmm3
691         movq    (XMM4 *8+offes_fltregs)(%rbp),%xmm4
692         movq    (XMM5 *8+offes_fltregs)(%rbp),%xmm5
693         movq    (XMM6 *8+offes_fltregs)(%rbp),%xmm6
694         movq    (XMM7 *8+offes_fltregs)(%rbp),%xmm7
695         movq    (XMM8 *8+offes_fltregs)(%rbp),%xmm8
696         movq    (XMM9 *8+offes_fltregs)(%rbp),%xmm9
697         movq    (XMM10*8+offes_fltregs)(%rbp),%xmm10
698         movq    (XMM11*8+offes_fltregs)(%rbp),%xmm11
699         movq    (XMM12*8+offes_fltregs)(%rbp),%xmm12
700         movq    (XMM13*8+offes_fltregs)(%rbp),%xmm13
701         movq    (XMM14*8+offes_fltregs)(%rbp),%xmm14
702         movq    (XMM15*8+offes_fltregs)(%rbp),%xmm15
703
704         mov     (RAX*8+offes_intregs)(%rbp),%rax
705         mov     (RBX*8+offes_intregs)(%rbp),%rbx
706         mov     (RCX*8+offes_intregs)(%rbp),%rcx
707         mov     (RDX*8+offes_intregs)(%rbp),%rdx
708         mov     (RSI*8+offes_intregs)(%rbp),%rsi
709         mov     (RDI*8+offes_intregs)(%rbp),%rdi
710         mov     (R8 *8+offes_intregs)(%rbp),%r8
711         mov     (R9 *8+offes_intregs)(%rbp),%r9
712         mov     (R10*8+offes_intregs)(%rbp),%r10
713         mov     (R11*8+offes_intregs)(%rbp),%r11
714         mov     (R12*8+offes_intregs)(%rbp),%r12
715         mov     (R13*8+offes_intregs)(%rbp),%r13
716         mov     (R14*8+offes_intregs)(%rbp),%r14
717         mov     (R15*8+offes_intregs)(%rbp),%r15
718
719         mov     (RBP*8+offes_intregs)(%rbp),%rbp
720
721         /* jump to new code */
722         ret
723
724
725 /* asm_builtin_x2x *************************************************************
726 *                                                                              *
727 *   Wrapper functions for float to int corner cases                            *
728 *                                                                              *
729 *******************************************************************************/
730
731 asm_builtin_f2i:
732         sub     $(ARG_CNT*8),sp
733         
734         SAVE_ARGUMENT_REGISTERS(0)
735         
736         movq    ftmp1,fa0
737         call    builtin_f2i@PLT
738         
739         RESTORE_ARGUMENT_REGISTERS(0)
740         
741         add     $(ARG_CNT*8),sp
742         ret
743
744
745 asm_builtin_f2l:
746         sub     $(ARG_CNT*8),sp
747         
748         SAVE_ARGUMENT_REGISTERS(0)
749         
750         movq    ftmp1,fa0
751         call    builtin_f2l@PLT
752         
753         RESTORE_ARGUMENT_REGISTERS(0)
754         
755         add     $(ARG_CNT*8),sp
756         ret
757
758
759 asm_builtin_d2i:
760         sub     $(ARG_CNT*8),sp
761         
762         SAVE_ARGUMENT_REGISTERS(0)
763         
764         movq    ftmp1,fa0
765         call    builtin_d2i@PLT
766         
767         RESTORE_ARGUMENT_REGISTERS(0)
768         
769         add     $(ARG_CNT*8),sp
770         ret
771
772
773 asm_builtin_d2l:
774         sub     $(ARG_CNT*8),sp
775         
776         SAVE_ARGUMENT_REGISTERS(0)
777         
778         movq    ftmp1,fa0
779         call    builtin_d2l@PLT
780         
781         RESTORE_ARGUMENT_REGISTERS(0)
782         
783         add     $(ARG_CNT*8),sp
784         ret
785
786
787 asm_getclassvalues_atomic:
788 _crit_restart:
789 _crit_begin:
790         movl    offbaseval(a0),itmp1l
791         movl    offdiffval(a0),itmp2l
792         movl    offbaseval(a1),itmp3l
793 _crit_end:
794         movl    itmp1l,offcast_super_baseval(a2)
795         movl    itmp2l,offcast_super_diffval(a2)
796         movl    itmp3l,offcast_sub_baseval(a2)
797         ret
798
799         .data
800                 
801 asm_criticalsections:
802 #if defined(ENABLE_THREADS)
803         .quad   _crit_begin
804         .quad   _crit_end
805         .quad   _crit_restart
806 #endif
807         .quad 0
808
809
810 /* Disable exec-stacks, required for Gentoo ***********************************/
811
812 #if defined(__GCC__) && defined(__ELF__)
813         .section .note.GNU-stack,"",@progbits
814 #endif
815
816
817 /*
818  * These are local overrides for various environment variables in Emacs.
819  * Please do not remove this and leave it at the end of the file, where
820  * Emacs will automagically detect them.
821  * ---------------------------------------------------------------------
822  * Local variables:
823  * mode: asm
824  * indent-tabs-mode: t
825  * c-basic-offset: 4
826  * tab-width: 4
827  * End:
828  * vim:noexpandtab:sw=4:ts=4:
829  */