* src/vm/jit/s390/md.c,
[cacao.git] / src / vm / jit / s390 / 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 7367 2007-02-16 07:17:01Z pm $
34
35 */
36
37
38 #include "config.h"
39
40 #include "vm/jit/s390/arch.h"
41 #include "vm/jit/s390/md-abi.h"
42 #include "vm/jit/s390/md-asm.h"
43 #include "vm/jit/s390/offsets.h"
44
45 #include "vm/jit/abi-asm.h"
46 #include "vm/jit/methodheader.h"
47
48 /* Copy a call to a PIC function from gcc -S
49  * We setup a temporary literal pool pointer.
50  */
51
52 #define PIC_CALL(fun, magic)                                  \
53         bras itmp3, L_##magic##_lp_end                          ; \
54 L_##magic##_lp:                                             ; \
55 L_##magic##_lp_5:                                           ; \
56         .long fun@PLTOFF                                        ; \
57 L_##magic##_lp_4:                                           ; \
58         .long _GLOBAL_OFFSET_TABLE_-L_##magic##_lp              ; \
59 L_##magic##_lp_end:                                         ; \
60         l       itmp2,L_##magic##_lp_4-L_##magic##_lp(itmp3)    ; \
61         la      itmp2,0(itmp2,itmp3)                            ; \
62         l       itmp1,L_##magic##_lp_5-L_##magic##_lp(itmp3)    ; \
63         bas     %r14,0(itmp1,itmp2)                             
64
65         .text
66
67
68 /* export functions ***********************************************************/
69
70         .globl asm_vm_call_method
71         .globl asm_vm_call_method_int
72         .globl asm_vm_call_method_long
73         .globl asm_vm_call_method_float
74         .globl asm_vm_call_method_double
75         .globl asm_vm_call_method_exception_handler
76
77         .globl asm_call_jit_compiler
78
79         .globl asm_handle_exception
80         .globl asm_handle_nat_exception
81
82         .globl asm_abstractmethoderror
83
84         .globl asm_patcher_wrapper
85
86         .globl asm_replacement_out
87         .globl asm_replacement_in
88
89         .globl asm_builtin_f2i
90         .globl asm_builtin_f2l
91         .globl asm_builtin_d2i
92         .globl asm_builtin_d2l
93
94         .globl asm_criticalsections
95         .globl asm_getclassvalues_atomic
96
97
98 #if 0
99 asm_vm_call_method:
100 asm_vm_call_method_int:
101 asm_vm_call_method_long:
102 asm_vm_call_method_float:
103 asm_vm_call_method_double:
104 #endif
105 asm_vm_call_method_exception_handler:
106 #if 0
107 asm_call_jit_compiler:
108 #endif
109 asm_handle_exception:
110 asm_handle_nat_exception:
111 asm_abstractmethoderror:
112 asm_replacement_out:
113 asm_replacement_in:
114 asm_builtin_f2i:
115 asm_builtin_f2l:
116 asm_builtin_d2i:
117 asm_builtin_d2l:
118 asm_criticalsections:
119 asm_getclassvalues_atomic:
120         .long 0
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         .long   0                           /* catch type all                     */
137         .long   0                           /* handler pc                         */
138         .long   0                           /* end pc                             */
139         .long   0                           /* start pc                           */
140         .long   1                           /* extable size                       */
141         .long   0                           /* ALIGNMENT PADDING                  */
142         .long   0                           /* line number table  start           */
143         .long   0                           /* line number table  size            */
144         .long   0                           /* ALIGNMENT PADDING                  */
145         .long   0                           /* fltsave                            */
146         .long   0                           /* intsave                            */
147         .long   0                           /* isleaf                             */
148         .long   0                           /* IsSync                             */
149         .long   0                           /* frame size                         */
150         .long   0                           /* codeinfo pointer                   */
151
152
153 asm_vm_call_method:
154 asm_vm_call_method_int:
155 asm_vm_call_method_long:
156 asm_vm_call_method_float:
157 asm_vm_call_method_double:
158
159 /*
160
161 a0:   methodinfo *m
162 a1:   s4 vmargscount   ---> v0: java_objectheader *
163 a2:   vm_arg *vmargs
164 r14:  return address
165
166 96 ...     on stack parameters (none)
167 0 - 96     register save area
168 -------------------------------------------------- <- SP on asm_vm_... entry
169            local variables
170                    saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
171 ----------------------------------------- <- SP after stack frame allocation
172            arguments on stack
173 ---------------------------------------------------- <- SP on JIT code entry
174            saved return address (callee saved)
175
176 */
177
178
179 /*
180         Regiser usage:
181         itmp1: argument block pointer
182         itmp2: argument counter
183         s0: integer argument counter
184         s1: float argument counter
185         s2: integer register counter
186         s3: backup argument block pointer
187         s4: backup argument count
188 */
189
190         stm   %r6, %r15, 24(sp)               /* save callers regiters */
191         stm   a0, a2, 8(sp)                   /* save arguments */
192         ahi   sp, -8                          /* allocate stack space for local variables */
193         st    %r14, 0(sp)                     /* store RA once more at bottom of stack frame */
194
195         ltr   a1, a1                          /* maybe we have no args... */
196         je    L_no_args
197
198         lr    itmp2, a1                       /* load arg count */
199         lr    itmp1, a2                       /* load arg pointer */
200
201         ahi   itmp1, -sizevmarg               /* initialize arg pointer */
202         ahi   itmp2, 1                        /* initialize arg count */ 
203         lhi   s0, 0                           /* initialize integer arg counter */
204         lhi   s2, 0                           /* initialize integer register counter */
205         lhi   s1, 0                           /* initialize float arg counter */
206
207         lr    s4, a1                          /* backup arg count */
208         lr    s3, a2                          /* backup arg pointer */
209
210 L_register_copy:
211
212         ahi   itmp1, sizevmarg                /* forward arg pointer */
213         ahi   itmp2, -1                       /* decrement arg count */
214         je    L_register_copy_done            /* no arguments left */
215
216         tm    offvmargtype(itmp1), 0x02       /* is this a float/double type? */
217         jne   L_register_handle_float
218
219 L_register_handle_int:
220
221         chi   s2, INT_ARG_CNT                 /* are we out of integer arg registers ? */
222         je    L_register_copy                 /* yes, next loop */
223
224         tm    offvmargtype(itmp1), 0x01       /* is this a 2 word type ? */
225         jne   L_register_handle_long
226
227         ahi   s0, 1                           /* increment integer arg counter */
228         ahi   s2, 1                           /* increment integer register counter */
229
230         /* handle argument */
231
232         chi   s2, 1
233         je    L_handle_i0
234         chi   s2, 2
235         je    L_handle_i1
236         chi   s2, 3
237         je    L_handle_i2
238         chi   s2, 4
239         je    L_handle_i3
240         chi   s2, 5
241         je    L_handle_i4
242
243 L_register_handle_long:
244
245         chi   s2, (INT_ARG_CNT - 1)           /* are there 2 integer arg registers left ? */
246         jl    L_register_handle_long_continue /* yes */
247         lhi   s2, INT_ARG_CNT                 /* no, drop last register */
248         j     L_register_copy
249
250 L_register_handle_long_continue:
251
252         ahi   s0, 1                           /* increment integer arg counter */
253         ahi   s2, 2                           /* consume 2 integer arg registers */
254
255         /* handle argument */
256
257         chi   s2, 1
258         je    L_handle_l0
259         chi   s2, 2
260         je    L_handle_l1
261         chi   s2, 3
262         je    L_handle_l2
263         chi   s2, 4
264         je    L_handle_l3
265
266 L_register_handle_float:
267
268         chi   s1, FLT_ARG_CNT                 /* are we out of float arg registers */
269         je    L_register_copy                 /* no arg regisers left */
270
271         ahi   s1, 1                           /* increment float argument counter */
272
273         tm    offvmargtype(itmp1), 0x01       /* is this a 2 word type ? */
274         jne   L_register_handle_double
275
276         /* handle argument */
277
278         chi   s1, 1
279         je    L_handle_f0
280         chi   s1, 2
281         je    L_handle_f1
282
283 L_register_handle_double:
284
285         /* handle argument */
286
287         chi   s1, 1
288         je    L_handle_d0
289         chi   s1, 2
290         je    L_handle_d1
291
292 L_register_copy_done:
293
294 /*
295         Regiser usage:
296         itmp1: argument block pointer
297         itmp2: argument counter
298         s0: integer argument counter (initialized by previous code) 
299         s1: float argument counter (initialized by previous code)
300         s2: pointer to current argument on stack
301         s3: backup argument block pointer (used to initialize itmp1)
302             after used as backup of original stack pointer
303         s4: backup argument count (used to initialize itmp2)
304             after used as size of parameters on stack
305 */
306
307         lr    itmp2, s4                     /* restore argument counter */
308         lr    itmp1, s3                     /* restore argument block pointer */
309
310                                             /* calculate remaining arguments */
311         sr    s4, s0                        /* - integer arguments in registers */
312         sr    s4, s1                        /* - float arguments in registers */
313
314         lr    s3, sp                        /* backup stack pointer (does not alter CC) */
315
316         je    L_copy_done                   /* no arguments left for stack */
317
318         sll   s4, 3                         /* allocate 8 bytes per parameter on stack */       
319         sr    sp, s4                        /* allocate stack space for arguments */ 
320
321         lr    s2, sp                        /* points now to current argument on stack */
322
323         ahi   itmp1, -sizevmarg             /* initialize argument block pointer */
324         ahi   itmp2, 1                      /* initialize argument counter */
325
326 L_stack_copy_loop:
327
328         ahi   itmp1, sizevmarg              /* forward argument block pointer */
329         ahi   itmp2, -1                     /* decrement argument counter */
330         je    L_copy_done                   /* all arguments done */
331
332         tm    offvmargtype(itmp1), 0x0      /* is this a float/double type? */
333         jne   L_stack_handle_float
334
335 L_stack_handle_int:
336
337         ahi   s0, -1                         /* decrement number of integer arguments in regs */
338         jhe   L_stack_copy_loop              /* argument is in register */
339
340         tm    offvmargtype(itmp1), 0x01      /* is this a 2 word type ? */
341         jne   L_stack_handle_long
342
343         mvc   0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
344         ahi   s2, 4
345         j     L_stack_copy_loop
346
347 L_stack_handle_long:
348
349         mvc   0(8, s2), offvmargdata(itmp1)  /* copy long value */
350         ahi   s2, 8
351         j     L_stack_copy_loop
352
353 L_stack_handle_float:
354
355         ahi   s1, -1                         /* decrement number of float arguments in regs */
356         jhe   L_stack_copy_loop              /* argument is in register */
357
358         tm    offvmargtype(itmp1), 0x01      /* is this a 2 word type ? */
359         jne   L_stack_handle_double
360
361         mvc   0(4, s2), offvmargdata(itmp1)  /* copy float value */
362         ahi   s2, 4
363         j     L_stack_copy_loop
364
365 L_stack_handle_double:
366
367         mvc   0(8, s2), offvmargdata(itmp1)  /* copy double value */
368         ahi   s2, 8
369         j     L_stack_copy_loop
370
371 L_copy_done:
372
373         /* Now we call the compiler in a rather questionable way i needed
374          * some days to understand:
375          *
376          * We can't simply call asm_call_jit_compiler, but we have to call an 
377          * address loaded from memory like it is done in JIT code.
378          *
379          * This is because the compiler will intercept the instruction before 
380          * the call instruction, extract the address where the function pointer
381          * has been loaded from and overwrite it with the code entry.
382          *
383          * Arguments are passed in temporary registers.
384          */
385
386         /* load address of L_asm_call_jit_compiler into memory */
387
388         basr  mptr, 0                         /* store PC */
389 L_basr:
390         la    mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
391         st    mptr, 4(s3)                     /* store on stack */
392
393         l     itmp1, 8+8(s3)                  /* load methodinfo for compiler */
394         la    mptr, 4(s3)                     /* store **function in mptr for compiler */
395
396         /* call L_asm_call_jit_compiler like JIT code would do */
397
398         l     itmp3, 0(mptr)                  /* load address of target from memory */
399         basr  %r14, itmp3                     /* jump to target */
400
401         /* todo will s4 survive the call? */
402         ar    sp, s4                          /* remove stack space for arguments */
403
404 L_asm_vm_call_method_return:
405
406         ahi   sp, 8                           /* remove stack space for local variables */
407         lm    %r6, %r15, 24(sp)               /* restore callers registers */
408         br    %r14                            /* return */
409
410 /* .... */
411
412 L_no_args:
413         lr    s3, sp
414         j     L_copy_done
415
416 L_handle_i0:
417         l     a0, offvmargdata+4(itmp1)
418         j     L_register_copy
419 L_handle_i1:
420         l     a1, offvmargdata+4(itmp1)
421         j     L_register_copy
422 L_handle_i2:
423         l     a2, offvmargdata+4(itmp1)
424         j     L_register_copy
425 L_handle_i3:
426         l     a3, offvmargdata+4(itmp1)
427         j     L_register_copy
428 L_handle_i4:
429         l     a4, offvmargdata+4(itmp1)
430         j     L_register_copy
431
432 L_handle_l0:
433         lm    a0, a1, offvmargdata(itmp1)
434         j     L_register_copy
435 L_handle_l1:
436         lm    a1, a2, offvmargdata(itmp1)
437         j     L_register_copy
438 L_handle_l2:
439         lm    a2, a3, offvmargdata(itmp1)
440         j     L_register_copy
441 L_handle_l3:
442         lm    a3, a4, offvmargdata(itmp1)
443         j     L_register_copy
444
445 L_handle_f0:
446         le    fa0, offvmargdata(itmp1)
447         j     L_register_copy
448 L_handle_f1:
449         le    fa1, offvmargdata(itmp1)
450         j     L_register_copy
451
452 L_handle_d0:
453         ld    fa0, offvmargdata(itmp1)
454         j     L_register_copy
455 L_handle_d1:
456         ld    fa1, offvmargdata(itmp1)
457         j     L_register_copy
458
459
460 /****************** function asm_call_jit_compiler *****************************
461 *                                                                              *
462 *   invokes the compiler for untranslated JavaVM methods.                      *
463 *                                                                              *
464 *   itmp1: methodinfo pointer                                                  *
465 *   itmp2: method pointer                                                      *
466 *                                                                              *
467 *******************************************************************************/
468
469 /*
470
471 argument registers: arguments (like in JIT)
472
473         arguments on stack (like in JIT)
474 ------------------------------------------------------------- <- SP on entry
475
476         saved return address                                           \
477         stored volatile (in terms of C ABI) floag argument registers   | 
478 96      stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
479 0 - 96  register save area (C ABI)                                     /
480 -------------------------------------------------- <- SP for jit_asm_compile
481 */
482
483 /* This is called from a compiler stub.
484  * Arguments are already in registers and the stack is setup like in CACAO.
485  */
486
487 asm_call_jit_compiler:
488 L_asm_call_jit_compiler:
489
490 #       define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
491
492         ahi     sp,-ACJC_STACKFRAME        /* allocate stack space */
493
494         stm         %r2,%r5,96(sp)             /* store volatile int arg regs */
495         std     %f0,96+16(sp)              /* store volatile float arg regs */
496         std     %f2,96+24(sp)              
497         st      %r14,96+32(sp)             /* store return address */
498
499         /* load arguments */
500
501         lr      a0,itmp1                   /* pass methodinfo pointer            */
502         lr      a1,itmp2                   /* pass method pointer                */
503         la      a2,ACJC_STACKFRAME(sp)     /* pass java sp                       */
504         la      a3,0(%r14)                 /* pass return address, make sure bit 32 is 0 */
505
506         /* call jit_asm_compile in a PIC way */
507
508         bras    itmp2, L_bras_jac
509         .long   jit_asm_compile
510 L_bras_jac:
511         l       itmp2, 0(itmp2)
512         basr    %r14, itmp2
513
514         lr      pv, v0                     /* save return value */
515
516         lm      %r2,%r5,96(sp)             /* restore volatile int arg regs */
517         ld      %f0,96+16(sp)              /* restore volatile float arg regs */
518         ld      %f2,96+24(sp)              /* restore volatile float arg regs */
519         l       %r14,96+32(sp)             /* restore return address */
520         ahi     sp, ACJC_STACKFRAME        /* remove stack frame */
521
522 #if 0
523         ltr     v0,v0
524         je      L_asm_call_jit_compiler_exception
525 #endif
526
527 jit_code_entry:                        /* label to set breakpoint on */
528         br      pv                         /* call the method, it will return to the caller */
529
530
531 L_asm_call_jit_compiler_exception:
532 #if 0
533         call    exceptions_get_and_clear_exception@PLT
534         pop     xpc                         /* delete return address              */
535         sub     $3,xpc                      /* faulting address is ra - 3         */
536         jmp     L_asm_handle_exception
537 #endif
538         .long 0
539
540
541 #if 0
542 /* asm_handle_exception ********************************************************
543 *                                                                              *
544 *   This function handles an exception. It does not use the usual calling      *
545 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
546 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
547 *   the local exception table for a handler. If no one is found, it unwinds    *
548 *   stacks and continues searching the callers.                                *
549 *                                                                              *
550 *******************************************************************************/
551
552 asm_handle_nat_exception:
553         add     $8,sp                       /* clear return address of native stub*/
554                 
555 asm_handle_exception:
556 L_asm_handle_exception:                 /* required for PIC code              */
557         sub     $((ARG_CNT+TMP_CNT)*8),sp   /* create maybe-leaf stackframe       */
558
559         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
560         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
561
562         mov     $((ARG_CNT+TMP_CNT)*8),a3   /* prepare a3 for handle_exception    */
563         mov     $1,t0                       /* set maybe-leaf flag                */
564
565 L_asm_handle_exception_stack_loop:
566         sub     $(6*8),sp
567         mov     xptr,0*8(sp)                /* save exception pointer             */
568         mov     xpc,1*8(sp)                 /* save exception pc                  */
569         add     sp,a3                       /* calculate Java sp into a3...       */
570         add     $(6*8),a3
571         mov     a3,3*8(sp)                  /* ...and save it                     */
572         mov     t0,4*8(sp)                  /* save maybe-leaf flag               */
573
574         mov     xpc,a0                      /* exception pc                       */
575         call    codegen_get_pv_from_pc@PLT
576         mov     v0,2*8(sp)                  /* save data segment pointer          */
577         
578         mov     0*8(sp),a0                  /* pass exception pointer             */
579         mov     1*8(sp),a1                  /* pass exception pc                  */
580         mov     v0,a2                       /* pass data segment pointer          */
581         mov     3*8(sp),a3                  /* pass Java stack pointer            */
582         call    exceptions_handle_exception@PLT
583
584         test    v0,v0
585         jz      L_asm_handle_exception_not_catched
586
587         mov     v0,xpc                      /* move handlerpc into xpc            */
588         mov     0*8(sp),xptr                /* restore exception pointer          */
589         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
590         add     $(6*8),sp                   /* free stack frame                   */
591
592         test    t0,t0                       /* test for maybe-leaf flag           */
593         jz      L_asm_handle_exception_no_leaf
594
595         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
596         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
597
598         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
599
600 L_asm_handle_exception_no_leaf:
601         jmp     *xpc                        /* jump to the handler                */
602
603 L_asm_handle_exception_not_catched:
604         mov     0*8(sp),xptr                /* restore exception pointer          */
605         mov     2*8(sp),itmp3               /* restore data segment pointer       */
606         mov     4*8(sp),t0                  /* get maybe-leaf flag                */
607         add     $(6*8),sp
608
609         test    t0,t0
610         jz      L_asm_handle_exception_no_leaf_stack
611
612         add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
613         xor     t0,t0                       /* clear the isleaf flags             */
614
615 L_asm_handle_exception_no_leaf_stack:
616         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
617         add     sp,itmp2                    /* pointer to save area               */
618         
619         mov     IntSave(itmp3),a0l          /* a0l = saved int register count     */
620         test    a0l,a0l
621         je      noint
622         
623         cmp     $1,a0l
624         je      int1
625         cmp     $2,a0l
626         je      int2
627         cmp     $3,a0l
628         je      int3
629         cmp     $4,a0l
630         je      int4
631         
632         mov     -5*8(itmp2),s0
633 int4:   
634         mov     -4*8(itmp2),s1
635 int3:   
636         mov     -3*8(itmp2),s2
637 int2:   
638         mov     -2*8(itmp2),s3
639 int1:   
640         mov     -1*8(itmp2),s4
641
642         shl     $3,a0l                      /* multiply by 8 bytes                */
643         sub     a0,itmp2
644                 
645 noint:
646 #if 0
647         mov     FltSave(itmp3),a0l          /* a0l = saved flt register count     */
648         test    a0l,a0l
649         je      noflt
650         
651         cmpl    $1,a0l
652         je      flt1
653         cmpl    $2,a0l
654         je      flt2
655         cmpl    $3,a0l
656         je      flt3
657         cmpl    $4,a0l
658         je      flt4
659
660         movq    -5*8(itmp2),%xmm11
661 flt4:   
662         movq    -4*8(itmp2),%xmm12
663 flt3:   
664         movq    -3*8(itmp2),%xmm13
665 flt2:   
666         movq    -2*8(itmp2),%xmm14
667 flt1:   
668         movq    -1*8(itmp2),%xmm15
669                 
670 noflt:
671 #endif
672         mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
673         add     itmp2,sp                    /* unwind stack                       */
674
675                                             /* exception pointer is still set     */
676         pop     xpc                         /* the new xpc is return address      */
677         sub     $3,xpc                      /* subtract 3 bytes for call          */
678
679         xor     a3,a3                       /* prepare a3 for handle_exception    */
680         
681         jmp             L_asm_handle_exception_stack_loop
682
683
684 /* asm_abstractmethoderror *****************************************************
685
686    Creates and throws an AbstractMethodError.
687
688 *******************************************************************************/
689
690 asm_abstractmethoderror:
691         mov     sp,a0                       /* pass java sp                       */
692         add     $1*8,a0
693         mov     0*8(sp),a1                  /* pass exception address             */
694         sub     $3,a1
695         call    exceptions_asm_new_abstractmethoderror@PLT
696                                             /* exception pointer is return value  */
697         pop     xpc                         /* get exception address              */
698         sub     $3,xpc                      /* exception address is ra - 3        */
699         jmp     L_asm_handle_exception
700
701 #endif
702
703 /* asm_patcher_wrapper *********************************************************
704
705    XXX
706
707    Stack layout:
708      20   return address into JIT code (patch position)
709      16   pointer to virtual java_objectheader
710      12   machine code (which is patched back later)
711       8   unresolved class/method/field reference
712       4   data segment displacement from load instructions
713       0   patcher function pointer to call (pv afterwards)
714
715 *******************************************************************************/
716
717 asm_patcher_wrapper:
718 #       define  apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
719
720         ahi     sp, -apw_sfs                /* create stack frame */
721
722         /* store all volatile registers and a2, because we will touch it */
723
724         st      a2, 96(sp)
725         STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
726         STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
727
728         /* pass arguments */
729
730         la      a0, apw_sfs(sp)             /* pass SP of patcher stub */
731         lr      a1, pv                      /* pass PV (if NULL, use findmethod)  */
732         lhi     a2, 0                       /* pass RA (it's on the stack)        */
733
734         /* call patcher_wrapper */
735
736         bras    itmp1, L_apw_bras           /* call patcher_wrapper */
737         .long   patcher_wrapper
738 L_apw_bras:
739         l       itmp1, 0(itmp1)
740         basr    %r14, itmp1
741
742         /* store return value */
743
744         st      v0,0(sp)                    /* save return value */
745
746         /* restore volatile registers */
747
748         l       a2, 96(sp)
749         LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
750         LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
751
752         l       itmp3, 0(sp)                /* restore return value */
753         ltr     itmp3, itmp3                /* exception thrown ? */
754         jne     L_asm_patcher_wrapper_exception /* handle exception */
755         ahi     sp, apw_sfs                 /* remove stack frame */
756         l       itmp3, 20(sp)               /* load return address to JIT from stack */
757         br      itmp3                       /* return */
758
759 L_asm_patcher_wrapper_exception:
760         .long 0
761 #if 0
762         mov     itmp3,xptr                  /* get exception                      */
763         pop     xpc                         /* get and remove return address      */
764         jmp     L_asm_handle_exception
765 #endif
766
767 #if 0
768
769 /* asm_replacement_out *********************************************************
770
771    This code is jumped to from the replacement-out stubs that are executed
772    when a thread reaches an activated replacement point.
773
774    The purpose of asm_replacement_out is to read out the parts of the
775    execution state that cannot be accessed from C code, store this state,
776    and then call the C function replace_me.
777
778    Stack layout:
779       8                 start of stack inside method to replace
780       0   rplpoint *    info on the replacement point that was reached
781
782 *******************************************************************************/
783
784 /* some room to accomodate changes of the stack frame size during replacement */
785         /* XXX we should find a cleaner solution here */
786 #define REPLACEMENT_ROOM  512
787
788 asm_replacement_out:
789     /* create stack frame */
790         sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
791
792         /* save registers in execution state */
793         mov     %rax,(RAX*8+offes_intregs)(sp)
794         mov     %rbx,(RBX*8+offes_intregs)(sp)
795         mov     %rcx,(RCX*8+offes_intregs)(sp)
796         mov     %rdx,(RDX*8+offes_intregs)(sp)
797         mov     %rsi,(RSI*8+offes_intregs)(sp)
798         mov     %rdi,(RDI*8+offes_intregs)(sp)
799         mov     %rbp,(RBP*8+offes_intregs)(sp)
800         movq    $0  ,(RSP*8+offes_intregs)(sp) /* not used */
801         mov     %r8 ,(R8 *8+offes_intregs)(sp)
802         mov     %r9 ,(R9 *8+offes_intregs)(sp)
803         mov     %r10,(R10*8+offes_intregs)(sp)
804         mov     %r11,(R11*8+offes_intregs)(sp)
805         mov     %r12,(R12*8+offes_intregs)(sp)
806         mov     %r13,(R13*8+offes_intregs)(sp)
807         mov     %r14,(R14*8+offes_intregs)(sp)
808         mov     %r15,(R15*8+offes_intregs)(sp)
809
810         movq    %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
811         movq    %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
812         movq    %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
813         movq    %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
814         movq    %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
815         movq    %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
816         movq    %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
817         movq    %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
818         movq    %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
819         movq    %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
820         movq    %xmm10,(XMM10*8+offes_fltregs)(sp)
821         movq    %xmm11,(XMM11*8+offes_fltregs)(sp)
822         movq    %xmm12,(XMM12*8+offes_fltregs)(sp)
823         movq    %xmm13,(XMM13*8+offes_fltregs)(sp)
824         movq    %xmm14,(XMM14*8+offes_fltregs)(sp)
825         movq    %xmm15,(XMM15*8+offes_fltregs)(sp)
826
827         /* calculate sp of method */
828         mov     sp,itmp1
829         add     $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
830         mov     itmp1,(offes_sp)(sp)
831
832         /* pv must be looked up via AVL tree */
833         movq    $0,(offes_pv)(sp)
834
835         /* call replace_me */
836         mov     -8(itmp1),a0                /* rplpoint *                         */
837     mov     sp,a1                       /* arg1: execution state              */
838     call    replace_me@PLT              /* call C function replace_me         */
839     call    abort@PLT                   /* NEVER REACHED                      */
840
841 /* asm_replacement_in **********************************************************
842
843    This code writes the given execution state and jumps to the replacement
844    code.
845
846    This function never returns!
847
848    C prototype:
849       void asm_replacement_in(executionstate *es);
850
851 *******************************************************************************/
852
853 asm_replacement_in:
854         mov     a0,%rbp                     /* executionstate *es                 */
855
856         /* set new sp */
857         mov     (offes_sp)(%rbp),%rsp
858         
859         /* store address of new code */
860         push    (offes_pc)(%rbp)
861         
862         /* copy registers from execution state */
863         movq    (XMM0 *8+offes_fltregs)(%rbp),%xmm0
864         movq    (XMM1 *8+offes_fltregs)(%rbp),%xmm1
865         movq    (XMM2 *8+offes_fltregs)(%rbp),%xmm2
866         movq    (XMM3 *8+offes_fltregs)(%rbp),%xmm3
867         movq    (XMM4 *8+offes_fltregs)(%rbp),%xmm4
868         movq    (XMM5 *8+offes_fltregs)(%rbp),%xmm5
869         movq    (XMM6 *8+offes_fltregs)(%rbp),%xmm6
870         movq    (XMM7 *8+offes_fltregs)(%rbp),%xmm7
871         movq    (XMM8 *8+offes_fltregs)(%rbp),%xmm8
872         movq    (XMM9 *8+offes_fltregs)(%rbp),%xmm9
873         movq    (XMM10*8+offes_fltregs)(%rbp),%xmm10
874         movq    (XMM11*8+offes_fltregs)(%rbp),%xmm11
875         movq    (XMM12*8+offes_fltregs)(%rbp),%xmm12
876         movq    (XMM13*8+offes_fltregs)(%rbp),%xmm13
877         movq    (XMM14*8+offes_fltregs)(%rbp),%xmm14
878         movq    (XMM15*8+offes_fltregs)(%rbp),%xmm15
879
880         mov     (RAX*8+offes_intregs)(%rbp),%rax
881         mov     (RBX*8+offes_intregs)(%rbp),%rbx
882         mov     (RCX*8+offes_intregs)(%rbp),%rcx
883         mov     (RDX*8+offes_intregs)(%rbp),%rdx
884         mov     (RSI*8+offes_intregs)(%rbp),%rsi
885         mov     (RDI*8+offes_intregs)(%rbp),%rdi
886         mov     (R8 *8+offes_intregs)(%rbp),%r8
887         mov     (R9 *8+offes_intregs)(%rbp),%r9
888         mov     (R10*8+offes_intregs)(%rbp),%r10
889         mov     (R11*8+offes_intregs)(%rbp),%r11
890         mov     (R12*8+offes_intregs)(%rbp),%r12
891         mov     (R13*8+offes_intregs)(%rbp),%r13
892         mov     (R14*8+offes_intregs)(%rbp),%r14
893         mov     (R15*8+offes_intregs)(%rbp),%r15
894
895         mov     (RBP*8+offes_intregs)(%rbp),%rbp
896
897         /* jump to new code */
898         ret
899
900
901 /* asm_builtin_x2x *************************************************************
902 *                                                                              *
903 *   Wrapper functions for float to int corner cases                            *
904 *                                                                              *
905 *******************************************************************************/
906
907 asm_builtin_f2i:
908         sub     $(ARG_CNT*8),sp
909         
910         SAVE_ARGUMENT_REGISTERS(0)
911         
912         movq    ftmp1,fa0
913         call    builtin_f2i@PLT
914         
915         RESTORE_ARGUMENT_REGISTERS(0)
916         
917         add     $(ARG_CNT*8),sp
918         ret
919
920
921 asm_builtin_f2l:
922         sub     $(ARG_CNT*8),sp
923         
924         SAVE_ARGUMENT_REGISTERS(0)
925         
926         movq    ftmp1,fa0
927         call    builtin_f2l@PLT
928         
929         RESTORE_ARGUMENT_REGISTERS(0)
930         
931         add     $(ARG_CNT*8),sp
932         ret
933
934
935 asm_builtin_d2i:
936         sub     $(ARG_CNT*8),sp
937         
938         SAVE_ARGUMENT_REGISTERS(0)
939         
940         movq    ftmp1,fa0
941         call    builtin_d2i@PLT
942         
943         RESTORE_ARGUMENT_REGISTERS(0)
944         
945         add     $(ARG_CNT*8),sp
946         ret
947
948
949 asm_builtin_d2l:
950         sub     $(ARG_CNT*8),sp
951         
952         SAVE_ARGUMENT_REGISTERS(0)
953         
954         movq    ftmp1,fa0
955         call    builtin_d2l@PLT
956         
957         RESTORE_ARGUMENT_REGISTERS(0)
958         
959         add     $(ARG_CNT*8),sp
960         ret
961
962
963 asm_getclassvalues_atomic:
964 _crit_restart:
965 _crit_begin:
966         movl    offbaseval(a0),itmp1l
967         movl    offdiffval(a0),itmp2l
968         movl    offbaseval(a1),itmp3l
969 _crit_end:
970         movl    itmp1l,offcast_super_baseval(a2)
971         movl    itmp2l,offcast_super_diffval(a2)
972         movl    itmp3l,offcast_sub_baseval(a2)
973         ret
974
975         .data
976                 
977 asm_criticalsections:
978 #if defined(ENABLE_THREADS)
979         .quad   _crit_begin
980         .quad   _crit_end
981         .quad   _crit_restart
982 #endif
983         .quad 0
984
985
986 /* Disable exec-stacks, required for Gentoo ***********************************/
987
988 #if defined(__GCC__) && defined(__ELF__)
989         .section .note.GNU-stack,"",@progbits
990 #endif
991
992
993 #endif /* if 0 */
994
995 /*
996  * These are local overrides for various environment variables in Emacs.
997  * Please do not remove this and leave it at the end of the file, where
998  * Emacs will automagically detect them.
999  * ---------------------------------------------------------------------
1000  * Local variables:
1001  * mode: asm
1002  * indent-tabs-mode: t
1003  * c-basic-offset: 4
1004  * tab-width: 4
1005  * End:
1006  * vim:noexpandtab:sw=4:ts=4:
1007  */