Merged with tip.
[cacao.git] / src / vm / jit / mips / asmpart.S
1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
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/mips/md-abi.h"
31 #include "vm/jit/mips/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
40
41 /* export functions ***********************************************************/
42
43         .globl asm_vm_call_method
44         .globl asm_vm_call_method_int
45         .globl asm_vm_call_method_long
46         .globl asm_vm_call_method_float
47         .globl asm_vm_call_method_double
48         .globl asm_vm_call_method_exception_handler
49         .globl asm_vm_call_method_end
50
51         .globl asm_handle_exception
52         .globl asm_handle_nat_exception
53
54         .globl asm_abstractmethoderror
55
56         .globl compare_and_swap
57
58
59 /* asm_vm_call_method **********************************************************
60 *                                                                              *
61 *   This function calls a Java-method (which possibly needs compilation)       *
62 *   with up to 4 address parameters.                                           *
63 *                                                                              *
64 *   This functions calls the JIT-compiler which eventually translates the      *
65 *   method into machine code.                                                  *
66 *                                                                              *
67 *   A possibly throwed exception will be returned to the caller as function    *
68 *   return value, so the java method cannot return a fucntion value (this      *
69 *   function usually calls 'main' and '<clinit>' which do not return a         *
70 *   function value).                                                           *
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 #if SIZEOF_VOID_P == 8
83
84         .word   0                           /* fltsave                            */
85         .word   0                           /* intsave                            */
86         .word   0                           /* isleaf                             */
87         .word   0                           /* frame size                         */
88         .dword  0                           /* codeinfo pointer                   */
89
90 #else /* SIZEOF_VOID_P == 8 */
91
92         .word   0                           /* fltsave                            */
93         .word   0                           /* intsave                            */
94         .word   0                           /* isleaf                             */
95         .word   0                           /* frame size                         */
96         .word   0                           /* method pointer (pointer to name)   */
97
98 #endif /* SIZEOF_VOID_P == 8 */
99
100 asm_vm_call_method:
101 asm_vm_call_method_int:
102 asm_vm_call_method_long:
103 asm_vm_call_method_float:
104 asm_vm_call_method_double:
105         .set    noreorder                 /* XXX we need to recompute pv          */
106
107         aaddiu  sp,sp,-12*8               /* allocate stack space (only 11 needed)*/
108         ast     ra,0*8(sp)                /* save return address                  */
109
110         bal     L_asm_vm_call_method_compute_pv
111         ast     pv,1*8(sp)                /* procedure vector                     */
112 L_asm_vm_call_method_compute_pv:
113         aaddiu  pv,ra,-4*4
114
115         ast     s0,3*8(sp)                /* save callee saved register           */
116         ast     a0,4*8(sp)                /* save method PV                       */
117
118 #if SIZEOF_VOID_P == 8
119         sdc1    fss0,5*8(sp)              /* save non JavaABI saved flt registers */
120         sdc1    fss1,6*8(sp)
121         sdc1    fss2,7*8(sp)
122         sdc1    fss3,8*8(sp)
123         sdc1    fss4,9*8(sp)
124         sdc1    fss5,10*8(sp)
125 #endif
126
127         move    t0,a1                     /* address of data structure            */
128         move    t1,a2                     /* stack argument count                 */
129         move    s0,sp                     /* save stack pointer                   */
130
131 #if SIZEOF_VOID_P == 8
132
133         ld      a0,0*8(t0)
134         ld      a1,1*8(t0)
135         ld      a2,2*8(t0)
136         ld      a3,3*8(t0)
137         ld      a4,4*8(t0)
138         ld      a5,5*8(t0)
139         ld      a6,6*8(t0)
140         ld      a7,7*8(t0)
141
142         ldc1    fa0,8*8(t0)
143         ldc1    fa1,9*8(t0)
144         ldc1    fa2,10*8(t0)
145         ldc1    fa3,11*8(t0)
146         ldc1    fa4,12*8(t0)
147         ldc1    fa5,13*8(t0)
148         ldc1    fa6,14*8(t0)
149         ldc1    fa7,15*8(t0)
150
151 #else /* SIZEOF_VOID_P == 8 */
152
153 # if WORDS_BIGENDIAN == 1
154         lw      a0,0*8+4(t0)
155         lw      a1,1*8+4(t0)
156         lw      a2,2*8+4(t0)
157         lw      a3,3*8+4(t0)
158 # else
159         lw      a0,0*8(t0)
160         lw      a1,1*8(t0)
161         lw      a2,2*8(t0)
162         lw      a3,3*8(t0)
163 # endif
164
165 # if !defined(ENABLE_SOFT_FLOAT)
166         ldc1    fa0,4*8(t0)
167         ldc1    fa1,5*8(t0)
168 # endif
169
170 #endif /* SIZEOF_VOID_P == 8 */
171
172         beqz    t1,L_asm_vm_call_method_stack_copy_done
173         nop
174
175         sll     t2,t1,3                   /* calculate stackframe size (* 8)      */
176         asubu   sp,sp,t2                  /* create stackframe                    */
177         move    t2,sp                     /* temporary stack pointer              */
178
179 L_asm_vm_call_method_stack_copy_loop:
180 #if SIZEOF_VOID_P == 8
181         ld      t3,16*8(t0)               /* load argument                        */
182         sd      t3,0(t2)                  /* store argument on stack              */
183 #else
184 # if !defined(ENABLE_SOFT_FLOAT)
185         lw      t3,6*8+0(t0)              /* load argument                        */
186         lw      t4,6*8+4(t0)
187         sw      t3,0(t2)                  /* store argument on stack              */
188         sw      t4,4(t2)
189 # else
190 #  error implement me
191 # endif
192 #endif
193
194         aaddi   t1,t1,-1                  /* subtract 1 argument                  */
195         aaddi   t0,t0,8                   /* load address of next argument        */
196         aaddi   t2,t2,8                   /* increase stack pointer               */
197
198         bgtz    t1,L_asm_vm_call_method_stack_copy_loop
199         nop
200
201 L_asm_vm_call_method_stack_copy_done:
202         ala     mptr,4*8(s0)              /* get address of PV                    */
203         ald     pv,0*8(mptr)              /* load PV                              */
204         jalr    pv
205         nop
206 L_asm_vm_call_method_recompute_pv:
207 #if SIZEOF_VOID_P == 8
208         aaddiu  pv,ra,-76*4               /* recompute procedure vector           */
209 #else
210         aaddiu  pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
211 #endif
212
213         .set    reorder                   /* XXX we need to recompute pv          */
214
215 calljava_return2:
216         move    sp,s0                     /* restore stack pointer                */
217
218         ald     ra,0*8(sp)                /* restore return address               */
219         ald     pv,1*8(sp)                /* restore procedure vector             */
220         ald     s0,3*8(sp)
221
222 #if SIZEOF_VOID_P == 8
223         ldc1    fss0,5*8(sp)              /* restore non JavaABI saved flt regs   */
224         ldc1    fss1,6*8(sp)
225         ldc1    fss2,7*8(sp)
226         ldc1    fss3,8*8(sp)
227         ldc1    fss4,9*8(sp)
228         ldc1    fss5,10*8(sp)
229 #endif
230
231         aaddiu  sp,sp,12*8                /* free stack space                     */
232         j       ra                        /* return                               */
233
234 asm_vm_call_method_exception_handler:
235         move    sp,s0                     /* restore stack pointer                */
236 #if SIZEOF_VOID_P == 4
237         aaddiu  sp,sp,-4*4                /* reserve space for 1 argument         */
238 #endif
239
240         move    a0,itmp1                  
241         jal     builtin_throw_exception
242 #if SIZEOF_VOID_P == 4
243         aaddiu  sp,sp,4*4
244 #endif
245 asm_vm_call_method_end:
246         b       calljava_return2
247
248         .end    asm_vm_call_method
249
250
251 /* asm_handle_exception ********************************************************
252
253    This function handles an exception. It does not use the usual calling
254    conventions. The exception pointer is passed in REG_ITMP1 and the
255    pc from the exception raising position is passed in REG_ITMP2. It searches
256    the local exception table for a handler. If no one is found, it unwinds
257    stacks and continues searching the callers.
258
259 *******************************************************************************/
260
261         .ent    asm_handle_nat_exception
262
263 asm_handle_nat_exception:
264 L_asm_handle_exception_stack_loop:
265 #if SIZEOF_VOID_P == 8
266         aaddiu  sp,sp,-6*8                  /* keep stack 16-byte aligned         */
267         ast     xptr,0*8(sp)                /* save exception pointer             */
268         ast     xpc,1*8(sp)                 /* save exception pc                  */
269         ast     ra,3*8(sp)                  /* save RA                            */
270         ast     zero,4*8(sp)                /* save maybe-leaf flag (cleared)     */
271 #else
272         aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
273         ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
274         ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
275         ast     ra,4*4+3*8(sp)              /* save return address                */
276         ast     zero,4*4+4*8(sp)            /* save maybe-leaf flag (cleared)     */
277 #endif
278
279         move    a0,ra                       /* pass RA                            */
280         jal     md_asm_codegen_get_pv_from_pc /* get PV from RA                   */
281
282 #if SIZEOF_VOID_P == 8
283         ast     v0,2*8(sp)                  /* save PV                            */
284
285         ald     a0,0*8(sp)                  /* pass xptr                          */
286         ald     a1,1*8(sp)                  /* pass xpc                           */
287         move    a2,v0                       /* pass PV                            */
288         aaddiu  a3,sp,6*8                   /* pass Java SP                       */
289 #else
290         ast     v0,4*4+2*8(sp)              /* save data segment pointer          */
291
292         ald     a0,4*4+0*8(sp)              /* pass exception pointer             */
293         ald     a1,4*4+1*8(sp)              /* pass exception pc                  */
294         move    a2,v0                       /* pass data segment pointer          */
295         aaddiu  a3,sp,(4*4+6*8)             /* pass Java stack pointer            */
296 #endif
297
298         b       L_asm_handle_exception_continue
299
300         .aent    asm_handle_exception
301
302 asm_handle_exception:
303         aaddiu  sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
304
305         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
306         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
307
308 #if SIZEOF_VOID_P == 8
309         aaddiu  sp,sp,-6*8                  /* allocate stack                     */
310         ast     xptr,0*8(sp)                /* save exception pointer             */
311         ast     pv,2*8(sp)                  /* save PV                            */
312         ast     ra,3*8(sp)                  /* save RA                            */
313         addu    t0,zero,1                   /* set maybe-leaf flag                */
314         ast     t0,4*8(sp)                  /* save maybe-leaf flag               */
315 #else
316         aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
317         ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
318         ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
319         ast     pv,4*4+2*8(sp)              /* save data segment pointer          */
320         ast     ra,4*4+3*8(sp)              /* save return address                */
321         addu    t0,zero,1                   /* set maybe-leaf flag                */
322         ast     t0,4*4+4*8(sp)              /* save maybe-leaf flag               */
323 #endif
324
325         move    a0,xptr                     /* pass xptr                          */
326         move    a1,xpc                      /* pass xpc                           */
327         move    a2,pv                       /* pass PV                            */
328
329 #if SIZEOF_VOID_P == 8
330         aaddiu  a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP                       */
331 #else
332         aaddiu  a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer        */
333 #endif
334
335 L_asm_handle_exception_continue:
336         jal     exceptions_handle_exception
337         
338         beqz    v0,L_asm_handle_exception_not_catched
339
340         move    xpc,v0                      /* move handlerpc into xpc            */
341
342 #if SIZEOF_VOID_P == 8
343         ald     xptr,0*8(sp)                /* restore exception pointer          */
344         ald     pv,2*8(sp)                  /* restore PV                         */
345         ald     ra,3*8(sp)                  /* restore RA                         */
346         ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
347         aaddiu  sp,sp,6*8                   /* free stackframe                    */
348 #else
349         ald     xptr,4*4+0*8(sp)            /* restore exception pointer          */
350         ald     pv,4*4+2*8(sp)              /* restore data segment pointer       */
351         ald     ra,4*4+3*8(sp)              /* restore return address             */
352         ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
353         aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
354 #endif
355         
356         beqz    t0,L_asm_handle_exception_no_leaf
357
358         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
359         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
360         
361         aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
362
363 L_asm_handle_exception_no_leaf:
364         jr      xpc                         /* jump to the handler                */
365
366 L_asm_handle_exception_not_catched:
367 #if SIZEOF_VOID_P == 8
368         ald     xptr,0*8(sp)                /* restore xptr                       */
369         ald     pv,2*8(sp)                  /* restore PV                         */
370         ald     ra,3*8(sp)                  /* restore RA                         */
371         ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
372         aaddiu  sp,sp,6*8                   /* free stackframe                    */
373 #else
374         ald     xptr,4*4+0*8(sp)            /* restore xptr                       */
375         ald     pv,4*4+2*8(sp)              /* restore PV                         */
376         ald     ra,4*4+3*8(sp)              /* restore RA                         */
377         ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
378         aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
379 #endif
380         
381         beqz    t0,L_asm_handle_exception_no_leaf_stack
382
383         aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
384         move    t0,zero                     /* clear the maybe-leaf flag          */
385
386 L_asm_handle_exception_no_leaf_stack:
387         lw      t1,FrameSize(pv)            /* get frame size                     */
388         aaddu   t1,sp,t1                    /* pointer to save area               */
389
390         lw      t2,IsLeaf(pv)               /* is leaf procedure                  */
391         bnez    t2,L_asm_handle_exception_no_ra_restore
392
393         ald     ra,-1*8(t1)                 /* restore ra                         */
394         aaddiu  t1,t1,-8                    /* t1--                               */
395
396 L_asm_handle_exception_no_ra_restore:
397         move    xpc,ra                      /* the new xpc is ra                  */
398         lw      t2,IntSave(pv)              /* t1 = saved int register count      */
399         ala     t3,ex_int2                  /* t3 = current pc                    */
400         sll     t2,t2,2                     /* t2 = register count * 4            */
401         asubu   t3,t3,t2                    /* t3 = IntSave - 4 * register count  */
402         jr      t3                          /* jump to save position              */
403
404         ald     s0,-8*8(t1)
405         ald     s1,-7*8(t1)
406         ald     s2,-6*8(t1)
407         ald     s3,-5*8(t1)
408         ald     s4,-4*8(t1)
409         ald     s5,-3*8(t1)
410         ald     s6,-2*8(t1)
411         ald     s7,-1*8(t1)
412
413 ex_int2:
414         sll     t2,t2,1               /* t2 = register count * 4 * 2              */
415         asubu   t1,t1,t2              /* t1 = t0 - 8 * register count             */
416
417         lw      t2,FltSave(pv)        /* t2 = saved flt register count            */
418         ala     t3,ex_flt2            /* t3 = current pc                          */
419         sll     t2,t2,2               /* t2 = register count * 4                  */
420         asubu   t3,t3,t2              /* t3 = ex_int_sav - 4 * register count     */
421         jr      t3                          /* jump to save position              */
422
423 #if SIZEOF_VOID_P == 8
424         ldc1    fs0,-4*8(t1)
425         ldc1    fs1,-3*8(t1)
426         ldc1    fs2,-2*8(t1)
427         ldc1    fs3,-1*8(t1)
428 #else /* SIZEOF_VOID_P == 8 */
429 # if !defined(ENABLE_SOFT_FLOAT)
430         ldc1    fs0,-4*8(t1)
431         ldc1    fs1,-3*8(t1)
432         ldc1    fs2,-2*8(t1)
433         ldc1    fs3,-1*8(t1)
434         ldc1    fs4,-1*8(t1)
435         ldc1    fs5,-1*8(t1)
436 # endif /* !defined(ENABLE_SOFT_FLOAT) */
437 #endif /* SIZEOF_VOID_P == 8 */
438
439 ex_flt2:
440         lw      t1,FrameSize(pv)            /* get frame size                     */
441         aaddu   sp,sp,t1                    /* unwind stack                       */
442         b       L_asm_handle_exception_stack_loop
443
444         .end    asm_handle_nat_exception
445
446
447 /* asm_abstractmethoderror *****************************************************
448
449    Creates and throws an AbstractMethodError.
450
451 *******************************************************************************/
452
453         .ent    asm_abstractmethoderror
454
455 asm_abstractmethoderror:
456         aaddiu  sp,sp,-2*8                  /* create stackframe                  */
457         ast     ra,0*8(sp)                  /* save return address                */
458         aaddiu  a0,sp,2*8                   /* pass java sp                       */
459         move    a1,ra                       /* pass exception address             */
460         jal     exceptions_asm_new_abstractmethoderror
461         ald     ra,0*8(sp)                  /* restore return address             */
462         aaddiu  sp,sp,2*8                   /* remove stackframe                  */
463
464         move    xptr,v0                     /* get exception pointer              */
465         aaddiu  xpc,ra,-4                   /* exception address is ra - 4        */
466         b       asm_handle_nat_exception
467
468         .end    asm_abstractmethoderror
469
470
471         .ent    compare_and_swap
472
473 compare_and_swap:
474 1:
475         all     v0,0(a0)
476         bne     v0,a1,2f
477         move    t0,a2
478         asc     t0,0(a0)
479         beqz    t0,1b
480 2:
481         sync
482         j       ra
483
484         .end    compare_and_swap
485
486
487 /* disable exec-stacks ********************************************************/
488
489 #if defined(__linux__) && defined(__ELF__)
490         .section .note.GNU-stack,"",%progbits
491 #endif
492
493
494 /*
495  * These are local overrides for various environment variables in Emacs.
496  * Please do not remove this and leave it at the end of the file, where
497  * Emacs will automagically detect them.
498  * ---------------------------------------------------------------------
499  * Local variables:
500  * mode: asm
501  * indent-tabs-mode: t
502  * c-basic-offset: 4
503  * tab-width: 4
504  * End:
505  * vim:noexpandtab:sw=4:ts=4:
506  */