* src/vmcore/linker.c (build_display_inner): Use MNEW instead of malloc.
[cacao.git] / src / vm / jit / alpha / asmpart.S
1 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008 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/alpha/md-abi.h"
31 #include "vm/jit/alpha/md-asm.h"
32
33 #include "vm/jit/abi-asm.h"
34 #include "vm/jit/methodheader.h"
35
36
37         .text
38         .set    noat
39         .set    noreorder
40
41
42 /* export functions ***********************************************************/
43
44         .globl asm_vm_call_method
45         .globl asm_vm_call_method_int
46         .globl asm_vm_call_method_long
47         .globl asm_vm_call_method_float
48         .globl asm_vm_call_method_double
49         .globl asm_vm_call_method_exception_handler
50         .globl asm_vm_call_method_end
51
52         .globl asm_handle_exception
53         .globl asm_handle_nat_exception
54
55         .globl asm_abstractmethoderror
56
57         .globl asm_compare_and_swap
58         .globl asm_memory_barrier
59
60         .globl asm_md_init
61         .globl asm_cacheflush
62
63
64 /* asm_vm_call_method **********************************************************
65 *                                                                              *
66 *   This function calls a Java-method (which possibly needs compilation)       *
67 *   with up to 4 address parameters.                                           *
68 *                                                                              *
69 *   This functions calls the JIT-compiler which eventually translates the      *
70 *   method into machine code.                                                  *
71 *                                                                              *
72 *   C-prototype:                                                               *
73 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
74 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
75 *                                                                              *
76 *******************************************************************************/
77
78         .ent    asm_vm_call_method
79
80         .align  3
81
82         .long   0                           /* fltsave                            */
83         .long   1                           /* intsave                            */
84         .long   0                           /* isleaf                             */
85         .long   0                           /* frame size                         */
86         .quad   0                           /* codeinfo pointer                   */
87
88 asm_vm_call_method:
89 asm_vm_call_method_int:
90 asm_vm_call_method_long:
91 asm_vm_call_method_float:
92 asm_vm_call_method_double:
93         ldgp    gp,0(pv)
94         lda     sp,-5*8(sp)                 /* allocate stack space               */
95         stq     ra,0*8(sp)                  /* save return address                */
96         stq     gp,1*8(sp)                  /* save global pointer                */
97
98         stq     s0,3*8(sp)
99         stq     a0,4*8(sp)                  /* save method PV                     */
100
101         mov     a1,t0                       /* address of argument array          */
102         mov     a2,t1                       /* stack argument count               */
103         mov     sp,s0                       /* save stack pointer                 */
104
105         ldq     a0,0*8(t0)
106         ldq     a1,1*8(t0)
107         ldq     a2,2*8(t0)
108         ldq     a3,3*8(t0)
109         ldq     a4,4*8(t0)
110         ldq     a5,5*8(t0)
111
112         ldt     fa0,6*8(t0)
113         ldt     fa1,7*8(t0)
114         ldt     fa2,8*8(t0)
115         ldt     fa3,9*8(t0)
116         ldt     fa4,10*8(t0)
117         ldt     fa5,11*8(t0)
118
119         beq     t1,L_asm_vm_call_method_stack_copy_done
120
121         negq    t1,t2                       /* calculate stackframe size (* 8)    */
122         s8addq  t2,sp,sp                    /* create stackframe                  */
123         mov     sp,t2                       /* temporary stack pointer            */
124
125 L_asm_vm_call_method_stack_copy_loop:
126         ldq     t3,12*8(t0)                 /* load argument                      */
127         stq     t3,0(t2)                    /* store argument on stack            */
128
129         subq    t1,1,t1                     /* subtract 1 argument                */
130         addq    t0,8,t0                     /* load address of next argument      */
131         addq    t2,8,t2                     /* increase stack pointer             */
132
133         bgt     t1,L_asm_vm_call_method_stack_copy_loop
134
135 L_asm_vm_call_method_stack_copy_done:
136         lda     mptr,4*8(s0)                /* get address of PV                  */
137         ldq     pv,0*8(mptr)                /* load PV                            */
138         jmp     ra,(pv)
139 L_asm_vm_call_method_recompute_pv:
140         lda     pv,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)(ra)
141
142 L_asm_vm_call_method_recompute_return:
143         mov     s0,sp                       /* restore stack pointer              */
144
145         ldq     ra,0*8(sp)                  /* restore RA                         */
146         ldq     gp,1*8(sp)                  /* restore global pointer             */
147         ldq     s0,3*8(sp)
148
149         lda     sp,5*8(sp)                  /* free stack space                   */
150         jmp     zero,(ra)
151
152 asm_vm_call_method_exception_handler:
153         mov     s0,sp                       /* restore stack pointer              */
154         ldq     gp,1*8(sp)                  /* restore global pointer             */
155         mov     itmp1,a0
156         jsr     ra,builtin_throw_exception
157
158 asm_vm_call_method_end:                                 
159         br      L_asm_vm_call_method_recompute_return
160
161         .end    asm_vm_call_method
162
163
164 /* asm_handle_exception ********************************************************
165
166    This function handles an exception. It does not use the usual calling
167    conventions. The exception pointer is passed in REG_ITMP1 and the
168    pc from the exception raising position is passed in REG_ITMP2. It searches
169    the local exception table for a handler. If no one is found, it unwinds
170    stacks and continues searching the callers.
171
172    ATTENTION: itmp3 == gp!
173
174 *******************************************************************************/
175
176         .ent    asm_handle_nat_exception
177
178 asm_handle_nat_exception:
179 L_asm_handle_nat_exception:       /* required for PIC code                    */
180 L_asm_handle_exception_stack_loop:
181         lda     sp,-6*8(sp)                 /* keep stack 16-byte aligned         */
182         stq     xptr,0*8(sp)                /* save xptr                          */
183         stq     xpc,1*8(sp)                 /* save xpc                           */
184         stq     ra,3*8(sp)                  /* save RA                            */
185         stq     zero,4*8(sp)                /* save maybe-leaf flag (cleared)     */
186
187         mov     ra,a0                       /* pass RA                            */
188
189         br      ra,L_asm_handle_exception_load_gp
190 L_asm_handle_exception_load_gp:
191         ldgp    gp,0(ra)                    /* load gp                            */
192
193         jsr     ra,md_asm_codegen_get_pv_from_pc /* get PV from RA                */
194         stq     v0,2*8(sp)                  /* save PV                            */
195
196         ldq     a0,0*8(sp)                  /* pass xptr                          */
197         ldq     a1,1*8(sp)                  /* pass xpc                           */
198         mov     v0,a2                       /* pass PV                            */
199         addq    sp,6*8,a3                   /* pass Java SP                       */
200
201         br      L_asm_handle_exception_continue
202
203         .aent    asm_handle_exception
204
205 asm_handle_exception:
206 L_asm_handle_exception:                 /* required for PIC code              */
207         lda     sp,-(ARG_CNT+TMP_CNT)*8(sp) /* create maybe-leaf stackframe       */
208
209         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
210         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
211
212         lda     sp,-6*8(sp)                 /* keep stack 16-byte aligned         */
213         stq     xptr,0*8(sp)                /* save xptr                          */
214         stq     pv,2*8(sp)                  /* save PV                            */
215         stq     ra,3*8(sp)                  /* save RA                            */
216         lda     t0,1(zero)                  /* set maybe-leaf flag                */
217         stq     t0,4*8(sp)                  /* save maybe-leaf flag               */
218
219         br      ra,L_asm_handle_exception_load_gp_2
220 L_asm_handle_exception_load_gp_2:
221         ldgp    gp,0(ra)                    /* load gp                            */
222
223         mov     xptr,a0                     /* pass xptr                          */
224         mov     xpc,a1                      /* pass xpc                           */
225         mov     pv,a2                       /* pass PV                            */
226         lda     a3,(ARG_CNT+TMP_CNT+6)*8(sp)/* pass Java SP                       */
227
228 L_asm_handle_exception_continue:
229         jsr     ra,exceptions_handle_exception
230
231         beq     v0,L_asm_handle_exception_not_catched
232
233         mov     v0,xpc                      /* move handlerpc into xpc            */
234         ldq     xptr,0*8(sp)                /* restore xptr                       */
235         ldq     pv,2*8(sp)                  /* restore PV                         */
236         ldq     ra,3*8(sp)                  /* restore RA                         */
237         ldq     t0,4*8(sp)                  /* get maybe-leaf flag                */
238         lda     sp,6*8(sp)                  /* free stack frame                   */
239
240         beq     t0,L_asm_handle_exception_no_leaf
241
242         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
243         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
244         
245         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
246
247 L_asm_handle_exception_no_leaf:
248         jmp     zero,(xpc)                  /* jump to the handler                */
249
250 L_asm_handle_exception_not_catched:
251         ldq     xptr,0*8(sp)                /* restore xptr                       */
252         ldq     pv,2*8(sp)                  /* restore PV                         */
253         ldq     ra,3*8(sp)                  /* restore RA                         */
254         ldq     t0,4*8(sp)                  /* get maybe-leaf flag                */
255         lda     sp,6*8(sp)
256
257         beq     t0,L_asm_handle_exception_no_leaf_stack
258
259         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
260         mov     zero,t0                     /* clear the maybe-leaf flag          */
261
262 L_asm_handle_exception_no_leaf_stack:
263         ldl     t1,FrameSize(pv)            /* get frame size                     */
264         addq    t1,sp,t1                    /* pointer to save area               */
265
266         ldl     t2,IsLeaf(pv)               /* is leaf procedure                  */
267         bne     t2,L_asm_handle_exception_no_ra_restore
268
269         ldq     ra,-1*8(t1)                 /* restore ra                         */
270         subq    t1,8,t1                     /* t1--                               */
271
272 L_asm_handle_exception_no_ra_restore:
273         mov     ra,xpc                      /* the new xpc is ra                  */
274         ldl     t2,IntSave(pv)              /* t2 = saved int register count      */
275         br      t3,ex_int1                  /* t3 = current pc                    */
276 ex_int1:
277         lda     t3,(ex_int2 - ex_int1)(t3)
278         negl    t2,t2                       /* negate register count              */
279         s4addq  t2,t3,t3                    /* t2 = IntSave - register count * 4  */
280         jmp     zero,(t3)                   /* jump to save position              */
281
282         ldq     s0,-7*8(t1)
283         ldq     s1,-6*8(t1)
284         ldq     s2,-5*8(t1)
285         ldq     s3,-4*8(t1)
286         ldq     s4,-3*8(t1)
287         ldq     s5,-2*8(t1)
288         ldq     s6,-1*8(t1)
289
290 ex_int2:
291         s8addq  t2,t1,t1                    /* t1 = t1 - 8 * register count       */
292
293         ldl     t2,FltSave(pv)              /* t2 = saved flt register count      */
294         br      t3,ex_flt1                  /* t3 = current pc                    */
295 ex_flt1:
296         lda     t3,(ex_flt2 - ex_flt1)(t3)
297         negl    t2,t2                       /* negate register count              */
298         s4addq  t2,t3,t3                    /* t2 = FltSave - 4 * register count  */
299         jmp     zero,(t3)                   /* jump to save position              */
300
301         ldt     fs0,-8*8(t1)
302         ldt     fs1,-7*8(t1)
303         ldt     fs2,-6*8(t1)
304         ldt     fs3,-5*8(t1)
305         ldt     fs4,-4*8(t1)
306         ldt     fs5,-3*8(t1)
307         ldt     fs6,-2*8(t1)
308         ldt     fs7,-1*8(t1)
309
310 ex_flt2:
311         ldl     t1,FrameSize(pv)            /* get frame size                     */
312         addq    sp,t1,sp                    /* unwind stack                       */
313         br      L_asm_handle_exception_stack_loop
314
315         .end    asm_handle_nat_exception
316
317
318 /* asm_abstractmethoderror *****************************************************
319
320    Creates and throws an AbstractMethodError.
321
322 *******************************************************************************/
323
324         .ent    asm_abstractmethoderror
325
326 asm_abstractmethoderror:
327         subq    sp,2*8,sp                   /* create stackframe                  */
328         stq     ra,0*8(sp)                  /* save return address                */
329         addq    sp,2*8,a0                   /* pass java sp                       */
330         mov     ra,a1                       /* pass exception address             */
331         jsr     ra,exceptions_asm_new_abstractmethoderror
332         ldq     ra,0*8(sp)                  /* restore return address             */
333         addq    sp,2*8,sp                   /* remove stackframe                  */
334
335         mov     v0,xptr                     /* get exception pointer              */
336         subq    ra,4,xpc                    /* exception address is ra - 4        */
337         br      L_asm_handle_nat_exception
338
339         .end    asm_abstractmethoderror
340
341
342 /* asm_compare_and_swap ********************************************************
343
344    Does an atomic compare and swap.  Required for the lock
345    implementation.
346
347    Atomically do the following: Check if the location still contains
348    `oldval`. If so, replace it by `newval` and return `oldval`.
349
350    RETURN VALUE:
351        the old value at *p
352
353    long compare_and_swap(volatile long *p, long oldval, long newval);
354
355 *******************************************************************************/
356
357         .ent    asm_compare_and_swap
358
359 asm_compare_and_swap:
360 1:
361         ldq_l   v0,0(a0)
362         cmpeq   v0,a1,t0
363         beq     t0,2f
364         mov     a2,t0
365         stq_c   t0,0(a0)
366         beq     t0,1b
367 2:
368         jmp     zero,(ra)
369
370         .end    asm_compare_and_swap
371
372
373 /* asm_memory_barrier **********************************************************
374
375    A memory barrier for the Java Memory Model.
376
377 *******************************************************************************/
378
379         .ent    asm_memory_barrier
380
381 asm_memory_barrier:
382         mb
383         jmp     zero,(ra)
384
385         .end    asm_memory_barrier
386
387
388 /* asm_md_init *****************************************************************
389
390    Initialize machine dependent stuff.
391
392    Determines if the byte support instruction set (21164a and higher)
393    is available.
394
395 *******************************************************************************/
396
397         .ent    asm_md_init
398
399 asm_md_init:
400         .long   0x47e03c20                  /* amask   1,v0                       */
401         jmp     zero,(ra)                   /* return                             */
402
403         .end    asm_md_init
404
405
406 /* asm_cacheflush **************************************************************
407
408    XXX
409
410 *******************************************************************************/
411
412         .ent    asm_cacheflush
413
414 asm_cacheflush:
415         call_pal PAL_imb              /* synchronize instruction cache            */
416         jmp     zero,(ra)
417
418         .end    asm_cacheflush
419
420
421 /* disable exec-stacks ********************************************************/
422
423 #if defined(__linux__) && defined(__ELF__)
424         .section .note.GNU-stack,"",%progbits
425 #endif
426
427
428 /*
429  * These are local overrides for various environment variables in Emacs.
430  * Please do not remove this and leave it at the end of the file, where
431  * Emacs will automagically detect them.
432  * ---------------------------------------------------------------------
433  * Local variables:
434  * mode: asm
435  * indent-tabs-mode: t
436  * c-basic-offset: 4
437  * tab-width: 4
438  * End:
439  * vim:noexpandtab:sw=4:ts=4:
440  */