95d9be608b8b9ad80ca4ba747b5266bda72139ef
[cacao.git] / i386 / asmpart.S
1 /* -*- mode: asm; tab-width: 4 -*- */
2 /****************************** asmpart.c **************************************
3 *                                                                              *
4 *   It contains the Java-C interface functions for i386 processors.            *
5 *                                                                              *
6 *   Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst              *
7 *                                                                              *
8 *   See file COPYRIGHT for information on usage and disclaimer of warranties   *
9 *                                                                              *
10 *   Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at            *
11 *            Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at            *
12 *            Christian Thalinger                                               *
13 *                                                                              *
14 *   Last Change: $Id: asmpart.S 550 2003-11-01 20:34:14Z twisti $        *
15 *                                                                              *
16 *******************************************************************************/
17
18 #include "offsets.h"
19
20         .text
21
22
23 /********************* exported functions and variables ***********************/
24
25         .globl has_no_x_instr_set
26         .globl asm_calljavamethod
27         .globl asm_calljavafunction
28         .globl asm_call_jit_compiler
29         .globl asm_dumpregistersandcall
30         .globl asm_handle_exception
31         .globl asm_handle_nat_exception
32         .globl asm_builtin_checkcast    
33         .globl asm_builtin_checkarraycast
34         .globl asm_builtin_anewarray
35         .globl asm_builtin_newarray_array
36         .globl asm_builtin_aastore
37         .globl asm_builtin_monitorenter
38         .globl asm_builtin_monitorexit
39         .globl asm_builtin_ldiv
40         .globl asm_builtin_lrem
41     .globl asm_builtin_f2i
42     .globl asm_builtin_f2l
43     .globl asm_builtin_d2i
44     .globl asm_builtin_d2l
45         .globl asm_builtin_arrayinstanceof
46         .globl asm_perform_threadswitch
47         .globl asm_initialize_thread_stack
48         .globl asm_switchstackandcall
49         .globl asm_getcallingmethod
50     .globl asm_builtin_trace
51     .globl asm_builtin_exittrace
52     
53 /*************************** imported functions *******************************/
54
55         .globl jit_compile
56         .globl builtin_monitorexit
57         .globl builtin_throw_exception
58         .globl builtin_trace_exception
59         .globl class_java_lang_Object
60         .globl findmethod
61
62 /*********************** function has_no_x_instr_set ***************************
63 *                                                                              *
64 *   determines if the byte support instruction set (21164a and higher)         *
65 *   is available.                                                              *
66 *                                                                              *
67 *   Use it on i386 architecture to init the fpu.                               *
68 *                                                                              *
69 *******************************************************************************/
70
71 has_no_x_instr_set:
72                 finit                         /* intitialize the fpu                  */
73
74                 pushl   $0x027f   /* Round to nearest, 53-bit mode, exceptions masked */
75                 fldcw   (%esp)
76                 addl    $4,%esp
77                 
78                 xor             %eax,%eax                               /* result code 0 (not used for i386)  */
79                 ret
80
81
82 /********************* function asm_calljavamethod *****************************
83 *                                                                              *
84 *   This function calls a Java-method (which possibly needs compilation)       *
85 *   with up to 4 parameters.                                                   *
86 *                                                                              *
87 *   This functions calls the JIT-compiler which eventually translates the      *
88 *   method into machine code.                                                  *
89 *                                                                              *
90 *   An possibly throwed exception will be returned to the caller as function   *
91 *   return value, so the java method cannot return a fucntion value (this      *
92 *   function usually calls 'main' and '<clinit>' which do not return a         *
93 *   function value).                                                           *
94 *                                                                              *
95 *   C-prototype:                                                               *
96 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
97 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
98 *                                                                              *
99 *******************************************************************************/
100
101 #define         MethodPointer   -4
102 #define         FrameSize       -8
103 #define     IsSync          -12
104 #define     IsLeaf          -16
105 #define     IntSave         -20
106 #define     FltSave         -24
107 #define     ExTableSize     -28
108 #define     ExTableStart    -28
109
110 #define     ExEntrySize     -16
111 #define     ExStartPC       -4
112 #define     ExEndPC         -8
113 #define     ExHandlerPC     -12
114 #define     ExCatchType     -16
115
116 call_name:
117         .ascii  "calljavamethod\0\0"
118
119 /*      .align  3 */
120         .align  8
121         .long   0                         /* catch type all                       */
122         .long   calljava_xhandler         /* handler pc                           */
123         .long   calljava_xhandler         /* end pc                               */
124         .long   asm_calljavamethod        /* start pc                             */
125         .long   1                         /* extable size                         */
126         .long   0                         /* fltsave                              */
127         .long   0                         /* intsave                              */
128         .long   0                         /* isleaf                               */
129         .long   0                         /* IsSync                               */
130         .long   32                        /* frame size                           */
131         .long   0                         /* method pointer (pointer to name)     */
132
133 asm_calljavamethod:
134                 pushl   %ebp                  /* allocate stack space                 */
135                 movl    %esp, %ebp
136
137                 subl    $32,%esp              /* pass the remaining parameters        */
138                 xorl    %edx,%edx
139
140                 movl    %edx,28(%esp)         /* convert parms to 8 byte              */
141                 movl    24(%ebp),%eax
142                 movl    %eax,24(%esp)
143                 
144                 movl    %edx,20(%esp)
145                 movl    20(%ebp),%eax
146                 movl    %eax,16(%esp)
147
148                 movl    %edx,12(%esp)
149                 movl    16(%ebp),%eax
150                 movl    %eax,8(%esp)
151
152                 movl    %edx,4(%esp)
153                 movl    12(%ebp),%eax
154                 movl    %eax,(%esp)
155
156                 movl    8(%ebp),%eax          /* move function pointer to %eax        */
157
158                 lea             asm_call_jit_compiler,%ecx
159                 call    *%ecx                 /* call JIT compiler                    */
160                 
161 calljava_jit:
162 calljava_return:
163 calljava_ret:
164                 xorl    %eax,%eax
165                 leave                                             /* free stack space                     */
166                 ret
167
168 calljava_xhandler:
169                 pushl   %eax                              /* pass exception pointer               */
170                 call    builtin_throw_exception
171                 addl    $4,%esp
172                 addl    $32,%esp
173                 popl    %ebp
174                 ret
175
176
177 /********************* function asm_calljavafunction ***************************
178 *                                                                              *
179 *   This function calls a Java-method (which possibly needs compilation)       *
180 *   with up to 4 address parameters.                                           *
181 *                                                                              *
182 *   This functions calls the JIT-compiler which eventually translates the      *
183 *   method into machine code.                                                  *
184 *                                                                              *
185 *   C-prototype:                                                               *
186 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
187 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
188 *                                                                              *
189 *******************************************************************************/
190
191 call_name2:
192         .ascii  "calljavafunction\0\0"
193
194 /*      .align  3 */
195         .align  8
196         .long   0                         /* catch type all                       */
197         .long   calljava_xhandler2        /* handler pc                           */
198         .long   calljava_xhandler2        /* end pc                               */
199         .long   asm_calljavafunction      /* start pc                             */
200         .long   1                         /* extable size                         */
201         .long   0                         /* fltsave                              */
202         .long   0                         /* intsave                              */
203         .long   0                         /* isleaf                               */
204         .long   0                         /* IsSync                               */
205         .long   32                        /* frame size                           */
206         .long   0                         /* method pointer (pointer to name)     */
207
208 asm_calljavafunction:
209                 pushl   %ebp                  /* allocate stack space                 */
210                 movl    %esp, %ebp
211
212                 subl    $32,%esp              /* pass the remaining parameters        */
213                 xorl    %edx,%edx
214
215                 movl    %edx,28(%esp)         /* convert parms to 8 byte              */
216                 movl    24(%ebp),%eax
217                 movl    %eax,24(%esp)
218                 
219                 movl    %edx,20(%esp)
220                 movl    20(%ebp),%eax
221                 movl    %eax,16(%esp)
222
223                 movl    %edx,12(%esp)
224                 movl    16(%ebp),%eax
225                 movl    %eax,8(%esp)
226
227                 movl    %edx,4(%esp)
228                 movl    12(%ebp),%eax
229                 movl    %eax,(%esp)
230
231                 movl    8(%ebp),%eax          /* move function pointer to %eax        */
232
233                 lea             asm_call_jit_compiler,%ecx 
234                 call    *%ecx                 /* call JIT compiler                    */
235         
236 calljava_jit2:
237 calljava_return2:
238 calljava_ret2:
239                 leave
240                 ret
241
242 calljava_xhandler2:
243                 pushl   %eax                              /* pass exception pointer               */
244                 call    builtin_throw_exception
245                 addl    $4,%esp
246                 addl    $32,%esp
247                 popl    %ebp
248                 ret
249                                                 
250
251 /****************** function asm_call_jit_compiler *****************************
252 *                                                                              *
253 *   invokes the compiler for untranslated JavaVM methods.                      *
254 *                                                                              *
255 *   Register R0 contains a pointer to the method info structure (prepared      *
256 *   by createcompilerstub). Using the return address in R26 and the            *
257 *   offset in the LDA instruction or using the value in methodptr R28 the      *
258 *   patching address for storing the method address can be computed:           *
259 *                                                                              *
260 *   method address was either loaded using                                     *
261 *                                                                              *
262 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
263 *   i386_call_reg(REG_ITMP2)                                                   *
264 *                                                                              *
265 *   or                                                                         *
266 *                                                                              *
267 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
268 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
269 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
270 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
271 *   i386_call_reg(REG_ITMP1)                                                   *
272 *                                                                              *
273 *   in the static case the method pointer can be computed using the            *
274 *   return address and the lda function following the jmp instruction          *
275 *                                                                              *
276 *******************************************************************************/
277
278
279 asm_call_jit_compiler:
280         push    %ecx
281                 push    %ebx            /* save register                              */
282         push    %ebp
283                                 
284                 mov     12(%esp),%ebp   /* get return address (2 push)                */
285                 mov     -1(%ebp),%bl    /* get function code                          */
286                 cmp     $0xd2,%bl               /* called with `call *REG_ITMP2' (%edx)?      */
287                 jne             L_not_static_special
288
289                 sub     $6,%ebp                 /* calculate address of immediate             */
290                 jmp             L_call_jit_compile
291                 
292 L_not_static_special:
293                 cmp     $0xd0,%bl               /* called with `call *REG_ITMP1' (%eax)       */
294                 jne             L_not_virtual_interface
295                 
296                 sub     $6,%ebp         /* calculate address of offset                */
297                 mov     (%ebp),%ebp     /* get offset                                 */
298                 add     %edx,%ebp       /* add base address to get method address     */
299                 jmp             L_call_jit_compile
300
301 L_not_virtual_interface:        /* a call from asm_calljavamethod             */
302                 xor     %ebp,%ebp
303                 
304 L_call_jit_compile:
305                 push    %ebp            /* save address for method pointer            */
306
307                 push    %eax                    /* push methodpointer on stack                */
308                 call    jit_compile
309                 add     $4,%esp
310
311                 pop     %ebp            /* restore address for method pointer         */
312                 test    %ebp,%ebp               /* is address == 0 (asm_calljavamethod)       */
313                 je              L_call_method
314                 
315                 mov     %eax,(%ebp)             /* and now save the new pointer               */
316
317 L_call_method:
318         pop     %ebp
319                 pop     %ebx            /* restore registers                          */
320         pop     %ecx
321                         
322                 jmp             *%eax                   /* ...and now call the new method             */
323
324
325
326 /****************** function asm_dumpregistersandcall **************************
327 *                                                                              *
328 *   This funtion saves all callee saved registers and calls the function       *
329 *   which is passed as parameter.                                              *
330 *                                                                              *
331 *   This function is needed by the garbage collector, which needs to access    *
332 *   all registers which are stored on the stack. Unused registers are          *
333 *   cleared to avoid interferances with the GC.                                *
334 *                                                                              *
335 *   void asm_dumpregistersandcall (functionptr f);                             *
336 *                                                                              *
337 *******************************************************************************/
338
339 asm_dumpregistersandcall:
340         xor     %eax,%eax
341         mov     %eax,(%eax)
342         
343                 push    %ebx
344                 push    %ebp
345                 push    %esi
346                 push    %edi
347                                 
348                 mov     8(%ebp),%eax            /* load function pointer */
349                 call    *%eax                           /* call function */
350
351                 pop             %edi
352                 pop             %esi
353                 pop             %ebp
354                 pop             %ebx
355                 
356                 ret
357         
358
359 /********************* function asm_handle_exception ***************************
360 *                                                                              *
361 *   This function handles an exception. It does not use the usual calling      *
362 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
363 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
364 *   the local exception table for a handler. If no one is found, it unwinds    *
365 *   stacks and continues searching the callers.                                *
366 *                                                                              *
367 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
368 *                                                                              *
369 *******************************************************************************/
370
371 asm_handle_nat_exception:
372                 add     $4,%esp                                         /* clear return address of native stub */
373                 
374 asm_handle_exception:
375                 push    %eax
376                 push    %edx                                            /* get the data segment ptr       */
377                 call    findmethod
378                 mov     %eax,%ecx
379                 pop     %edx
380                 pop     %eax
381
382                 push    %ebp
383                 mov     %esp,%ebp
384
385                 push    %eax                                            /* save exception pointer         */
386 /*              subl    $2,%edx */
387                 push    %edx                                            /* save exception pc              */
388                 push    %ecx                                            /* save data segment pointer      */
389         
390                 push    %ebx
391                 push    %esi
392                 push    %edi
393                 
394 ex_stack_loop:
395                 sub     $16,%esp
396
397                 movl    %eax,(%esp)                                     /* exception pointer */
398
399                 movl    MethodPointer(%ecx),%eax        /* method pointer */
400                 movl    %eax,4(%esp)
401                 
402                 movl    %edx,8(%esp)                            /* exception pc */
403                 movl    $1,12(%esp)                                     /* set no unwind flag */
404                 call    builtin_trace_exception
405
406                 addl    $16,%esp
407
408                 movl    -12(%ebp),%esi                          /* %esi = data segment pointer */
409                 movl    ExTableSize(%esi),%ecx          /* %ecx = exception table size */
410                 test    %ecx,%ecx                                       /* if empty table skip */
411                 je              empty_table
412
413                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table */
414                 movl    -4(%ebp),%eax                           /* get xptr */
415                 
416 ex_table_loop:
417                 movl    -8(%ebp),%edx                           /* get xpc */
418                 
419                 movl    ExStartPC(%edi),%ebx            /* %ebx = exception start pc */
420                 cmpl    %edx,%ebx                                       /* %ebx = (startpc <= xpc) */
421                 jg              ex_table_cont                           /* if (false) continue */
422                 movl    ExEndPC(%edi),%ebx                      /* %ebx = exception end pc */
423                 cmpl    %ebx,%edx                                       /* %ebx = (xpc < endpc) */
424                 jge             ex_table_cont                           /* if (false) continue */
425                 movl    ExCatchType(%edi),%ebx          /* arg1 = exception catch type */
426                 test    %ebx,%ebx                                       /* NULL catches everything */
427                 je              ex_handle_it
428
429                 movl    offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr) */
430                 movl    offobjvftbl(%ebx),%ebx          /* %ebx = vftblptr(catchtype) class (not obj) */
431                 movl    offbaseval(%esi),%esi           /* %esi = baseval(xptr) */
432                 movl    offbaseval(%ebx),%edx           /* %edx = baseval(catchtype) */
433                 movl    offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype) */
434                 subl    %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
435                 cmpl    %ebx,%esi                                       /* xptr is instanceof catchtype */
436                 ja              ex_table_cont
437                 
438 ex_handle_it:
439                 movl    ExHandlerPC(%edi),%edx
440                 
441                 popl    %edi
442                 popl    %esi
443                 popl    %ebx
444         
445         popl    %eax                        /* pop %ecx (dummy) */
446         popl    %eax                        /* pop %edx (dummy) */
447         popl    %eax                        /* pop %eax */
448         
449                 leave
450
451                 jmp             *%edx
452
453 ex_table_cont:
454                 lea             ExEntrySize(%edi),%edi
455                 decl    %ecx
456                 test    %ecx,%ecx
457                 jg              ex_table_loop
458                 
459 empty_table:
460                 popl    %edi
461                 popl    %esi
462                 popl    %ebx
463                 popl    %ecx                                            /* restore data segment pointer   */
464                 popl    %edx
465                 popl    %eax                                            /* restore exception pointer      */
466                 popl    %ebp
467
468                 movl    %eax,%edi                                       /* save exception pointer         */
469                                 
470 ex_already_cleared:             
471                 movl    IsSync(%ecx),%eax                       /* %eax = SyncOffset              */
472                 test    %eax,%eax                                       /* if zero no monitorexit         */
473                 je              no_monitor_exit
474                 
475                 addl    %esp,%eax
476                 movl    -8(%eax),%eax
477         pusha                               /* save regs                      */
478                 pushl   %eax
479                 call    builtin_monitorexit
480                 addl    $4,%esp
481         popa                                /* restore regs                   */
482         
483 no_monitor_exit:
484                 movl    FrameSize(%ecx),%eax            /* %eax = frame size              */
485                 addl    %eax,%esp                                       /* unwind stack                   */
486                 movl    %esp,%eax                                       /* %eax = pointer to save area    */
487
488                 movl    IntSave(%ecx),%edx                      /* %edx = saved int register count */
489                 test    %edx,%edx
490                 je              noint
491                 cmpl    $1,%edx
492                 je              int1
493                 
494 int2:   
495                 movl    -16(%eax),%ebx
496
497 int1:   
498                 movl    -8(%eax),%ebp
499
500                 shll    $3,%edx                                         /* multiply by 8 bytes             */
501                 subl    %edx,%eax
502                 
503 noint:
504                 movl    FltSave(%ecx),%edx                      /* %edx = saved flt register count */
505                 test    %edx,%edx
506                 je              noflt
507                 cmpl    $1,%edx
508                 je              flt1
509                 cmpl    $2,%edx
510                 je              flt2
511                 cmpl    $3,%edx
512                 je              flt3
513                 
514 flt4:   
515                 fldl    -32(%eax)
516                 fstp    %st(1)
517
518 flt3:   
519                 fldl    -24(%eax)
520                 fstp    %st(2)
521                 
522 flt2:   
523                 fldl    -16(%eax)
524                 fstp    %st(3)
525                 
526 flt1:   
527                 fldl    -8(%eax)
528                 fstp    %st(4)
529                 
530 noflt:                                  
531                 popl    %edx                                            /* the new xpc is return address  */
532                 subl    $2,%edx
533                 
534                 pushl   %edx
535                 pushl   %ebx
536                 pushl   %ebp
537                 pushl   %esi
538                 pushl   %edi
539                                                                 
540                 pushl   %edx                                            /* get the new data segment ptr   */
541                 call    findmethod
542                 movl    %eax,%ecx
543                 addl    $4,%esp
544
545                 popl    %edi
546                 popl    %esi
547                 popl    %ebp
548                 popl    %ebx
549                 popl    %edx
550                 
551                 movl    %edi,%eax                                       /* restore saved exception pointer */
552                                 
553                 pushl   %ebp
554                 movl    %esp,%ebp
555
556                 pushl   %eax                                            /* save exception pointer         */
557                 pushl   %edx                                            /* save exception pc              */
558                 pushl   %ecx                                            /* save data segment pointer      */
559                 pushl   %ebx
560                 pushl   %esi
561                 pushl   %edi
562                 
563                 jmp             ex_stack_loop
564                 
565
566 /********************* function asm_builtin_monitorenter ***********************
567 *                                                                              *
568 *   Does null check and calls monitorenter or throws an exception              *
569 *                                                                              *
570 *******************************************************************************/
571
572 asm_builtin_monitorenter:
573                 cmpl    $0,4(%esp)
574                 je              nb_monitorenter                 /* if (null) throw exception          */
575                 jmp             builtin_monitorenter    /* else call builtin_monitorenter     */
576
577 nb_monitorenter:
578                 popl    %edx                                    /* delete return address */
579                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
580                 movl    proto_java_lang_NullPointerException,%eax
581                 jmp             asm_handle_exception
582                 
583
584 /********************* function asm_builtin_monitorexit ************************
585 *                                                                              *
586 *   Does null check and calls monitorexit or throws an exception               *
587 *                                                                              *
588 *******************************************************************************/
589
590 asm_builtin_monitorexit:
591                 cmpl    $0,4(%esp)
592                 je              nb_monitorexit                  /* if (null) throw exception          */
593                 jmp             builtin_monitorexit             /* else call builtin_monitorenter     */
594
595 nb_monitorexit:
596                 popl    %edx                                    /* delete return address */
597                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
598                 movl    proto_java_lang_NullPointerException,%eax
599                 jmp             asm_handle_exception
600
601
602 /************************ function asm_builtin_ldiv ****************************
603 *                                                                              *
604 *   Does null check and calls ldiv or throws an exception                      *
605 *                                                                              *
606 *******************************************************************************/
607
608 asm_builtin_ldiv:
609                 movl    12(%esp),%eax
610                 orl             16(%esp),%eax
611                 test    %eax,%eax                               /* if (null) throw exception */
612                 je              nb_ldiv
613
614                 jmp             builtin_ldiv
615
616 nb_ldiv:
617                 popl    %edx                                    /* delete return address */
618                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
619                 
620                 movl    proto_java_lang_ArithmeticException,%eax
621                 jmp             asm_handle_exception
622                                 
623
624 /************************ function asm_builtin_lrem ****************************
625 *                                                                              *
626 *   Does null check and calls lrem or throws an exception                      *
627 *                                                                              *
628 *******************************************************************************/
629
630 asm_builtin_lrem:
631                 movl    12(%esp),%eax
632                 orl             16(%esp),%eax
633                 test    %eax,%eax                               /* if (null) throw exception */
634                 je              nb_lrem
635
636                 jmp             builtin_lrem
637
638 nb_lrem:
639                 popl    %edx                                    /* delete return address */
640                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
641                 
642                 movl    proto_java_lang_ArithmeticException,%eax
643                 jmp             asm_handle_exception
644                 
645
646 /************************ function asm_builtin_x2x *****************************
647 *                                                                              *
648 *   Wrapper functions for corner cases                                         *
649 *                                                                              *
650 *******************************************************************************/
651
652 asm_builtin_f2i:
653         sub     $4,%esp
654         fsts    (%esp)
655         call    builtin_f2i
656         add     $4,%esp
657         ret             
658
659 asm_builtin_d2i:
660         sub     $8,%esp
661         fstl    (%esp)
662         call    builtin_d2i
663         add     $8,%esp
664         ret             
665
666 asm_builtin_f2l:
667         sub     $4,%esp
668         fsts    (%esp)
669         call    builtin_f2l
670         add     $4,%esp
671         ret             
672
673 asm_builtin_d2l:
674         sub     $8,%esp
675         fstl    (%esp)
676         call    builtin_d2l
677         add     $8,%esp
678         ret             
679
680         
681 /*********************** function new_builtin_checkcast ************************
682 *                                                                              *
683 *   Does the cast check and eventually throws an exception                     *
684 *                                                                              *
685 *******************************************************************************/
686
687 asm_builtin_checkcast:
688                 xorl    %eax,%eax
689                 movl    $0,(%eax)
690                 ret
691
692                 
693 /******************* function asm_builtin_checkarraycast ***********************
694 *                                                                              *
695 *   Does the cast check and eventually throws an exception                     *
696 *                                                                              *
697 *******************************************************************************/
698
699 asm_builtin_checkarraycast:
700                 subl    $8,%esp                                 /* build stack frame (2 * 4 bytes)    */
701
702                 movl    12(%esp),%eax           /* 8 (frame) + 4 (return)             */
703                 movl    %eax,(%esp)                             /* save object pointer                */
704
705                 movl    20(%esp),%eax
706                 movl    %eax,4(%esp)
707
708                 call    builtin_checkarraycast  /* builtin_checkarraycast             */
709         
710                 test    %eax,%eax               /* if (false) throw exception         */
711                 je              nb_carray_throw
712
713                 movl    12(%esp),%eax                   /* return object pointer              */
714                 addl    $8,%esp
715                 ret
716
717 nb_carray_throw:
718                 addl    $8,%esp
719                 
720                 popl    %edx                                    /* delete return address              */
721                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
722                 
723                 movl    proto_java_lang_ClassCastException,%eax
724                 jmp             asm_handle_exception
725
726                 
727 /******************* function asm_builtin_anewarray ****************************
728 *                                                                              *
729 *   Does the cast check and eventually throws an exception                     *
730 *                                                                              *
731 *******************************************************************************/
732
733 asm_builtin_anewarray:
734                 subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
735
736                 movl    12(%esp),%eax
737                 movl    %eax,(%esp)
738
739                 movl    20(%esp),%eax
740                 movl    %eax,4(%esp)
741
742                 call    builtin_anewarray
743         
744                 addl    $8,%esp
745                 ret
746
747                 
748 /******************* function asm_builtin_newarray_array ***********************
749 *                                                                              *
750 *   Does the cast check and eventually throws an exception                     *
751 *                                                                              *
752 *******************************************************************************/
753
754 asm_builtin_newarray_array:
755                 subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
756
757                 movl    12(%esp),%eax
758                 movl    %eax,(%esp)
759
760                 movl    20(%esp),%eax
761                 movl    %eax,4(%esp)
762
763                 call    builtin_newarray_array
764         
765                 addl    $8,%esp
766                 ret
767
768                 
769 /******************* function asm_builtin_aastore ******************************
770 *                                                                              *
771 *   Does the cast check and eventually throws an exception                     *
772 *                                                                              *
773 *******************************************************************************/
774
775 asm_builtin_aastore:
776                 subl    $12,%esp                                /* build stack frame (3 * 4 bytes)    */
777
778                 movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
779                 test    %eax,%eax                               /* if null pointer throw exception    */
780                 je              nb_aastore_null
781
782                 movl    offarraysize(%eax),%edx /* load size                          */
783                 movl    24(%esp),%ecx                   /* index                              */
784                 cmpl    %edx,%ecx                               /* do bound check                     */
785                 ja              nb_aastore_bound                /* if out of bounds throw exception   */
786
787                 shll    $2,%ecx                                 /* index * 4                          */
788                 addl    %eax,%ecx                               /* add index * 4 to arrayref          */
789                 
790                 movl    %ecx,8(%esp)                    /* save store position                */
791                 
792                 movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
793                 movl    %eax,(%esp)
794
795                 movl    32(%esp),%eax                   /* object is second argument          */
796                 movl    %eax,4(%esp)
797                 
798                 call    builtin_canstore                /* builtin_canstore(arrayref,object)  */
799
800                 test    %eax,%eax                               /* if (false) throw exception         */
801                 je              nb_aastore_throw
802
803                 movl    32(%esp),%eax
804                 movl    8(%esp),%ecx
805                 movl    %eax,offobjarrdata(%ecx)/* store objectptr in array           */
806                 
807                 addl    $12,%esp
808                 ret
809
810 nb_aastore_null:
811                 addl    $12,%esp
812                 popl    %edx                                    /* delete return address */
813                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
814                 
815                 movl    proto_java_lang_NullPointerException,%eax
816                 jmp             asm_handle_exception
817
818 nb_aastore_bound:
819                 addl    $12,%esp
820                 popl    %edx                                    /* delete return address */
821                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
822                 
823                 movl    proto_java_lang_ArrayIndexOutOfBoundsException,%eax
824                 jmp             asm_handle_exception
825                 
826 nb_aastore_throw:
827                 addl    $12,%esp
828                 popl    %edx                                    /* delete return address */
829                 subl    $2,%edx                                 /* faulting address is return adress - 2 */
830                 
831                 movl    proto_java_lang_ArrayStoreException,%eax
832                 jmp             asm_handle_exception
833
834                 
835 /******************* function asm_builtin_arrayinstanceof **********************
836 *                                                                              *
837 *   Does the instanceof check of arrays                                        *
838 *                                                                              *
839 *******************************************************************************/
840
841 asm_builtin_arrayinstanceof:
842                 subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
843
844                 movl    12(%esp),%eax
845                 movl    %eax,(%esp)
846
847                 movl    20(%esp),%eax
848                 movl    %eax,4(%esp)
849
850                 call    builtin_arrayinstanceof
851         
852                 addl    $8,%esp
853                 ret
854
855                 
856 /******************* function asm_initialize_thread_stack **********************
857 *                                                                              *
858 * initialized a thread stack                                                   *
859 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
860 *                                                                              *
861 *******************************************************************************/
862
863 asm_initialize_thread_stack:
864                 movl    8(%esp),%eax            /* (to)->stackEnd                     */
865                 subl    $36,%eax                                /* 4 bytes * 8 regs + 4 bytes func    */
866
867                 xorl    %edx,%edx
868                 movl    %edx,0(%eax)
869                 movl    %edx,4(%eax)
870                 movl    %edx,8(%eax)
871                 movl    %edx,12(%eax)
872                 movl    %edx,16(%eax)
873                 movl    %edx,20(%eax)
874                 movl    %edx,24(%eax)
875                 movl    %edx,28(%eax)
876
877                 movl    4(%esp),%edx            /* save (u1*) (func)                  */
878                 movl    %edx,32(%eax)
879
880                 ret                             /* return restorepoint in %eax        */
881
882
883 /******************* function asm_perform_threadswitch *************************
884 *                                                                              *
885 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
886 *                                                                              *
887 *   performs a threadswitch                                                    *
888 *                                                                              *
889 *******************************************************************************/
890
891 asm_perform_threadswitch:
892                 subl    $36,%esp
893
894                 movl    %eax,0(%esp)
895                 movl    %edx,4(%esp)
896                 movl    %ecx,8(%esp)
897                 movl    %ebx,12(%esp)
898                 movl    %esp,16(%esp)
899                 movl    %ebp,20(%esp)
900                 movl    %esi,24(%esp)
901                 movl    %edi,28(%esp)
902
903                 movl    36(%esp),%eax                   /* save current return address */
904                 movl    %eax,32(%esp)
905
906                 movl    40(%esp),%eax                   /* first argument **from */
907                 movl    %esp,0(%eax)
908
909                 movl    48(%esp),%eax                   /* third argument **stackTop */
910                 movl    %esp,0(%eax)
911
912                 movl    44(%esp),%eax                   /* second argument **to */
913                 movl    0(%eax),%esp                    /* load new stack pointer */
914
915                 movl    0(%esp),%eax
916                 movl    4(%esp),%edx
917                 movl    8(%esp),%ecx
918                 movl    12(%esp),%ebx
919                                                                                 /* skip stack pointer */
920                 movl    20(%esp),%ebp
921                 movl    24(%esp),%esi
922                 movl    28(%esp),%edi
923
924                 addl    $32,%esp                /* leave return address on stack      */
925                 ret
926                 
927
928 /********************* function asm_switchstackandcall *************************
929 *                                                                              *
930 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
931 *                                      void *p);                                       *
932 *                                                                              *
933 *   Switches to a new stack, calls a function and switches back.               *
934 *       a0      new stack pointer                                              *
935 *       a1      function pointer                                               *
936 *               a2              pointer to variable where stack top should be stored           *
937 *       a3      pointer to user data, is passed to the function                *
938 *                                                                              *
939 *******************************************************************************/
940
941 asm_switchstackandcall:
942                 movl    4(%esp),%edx                    /* first argument *stack */
943                 subl    $8,%edx                                 /* allocate new stack */
944
945                 movl    (%esp),%eax                             /* save return address on new stack */
946                 movl    %eax,(%edx)
947
948                 movl    %esp,4(%edx)                    /* save old stack pointer on new stack */
949
950                 movl    12(%esp),%eax                   /* third argument **stacktopsave */
951                 movl    %esp,(%eax)                             /* save old stack pointer to variable */
952
953                 movl    8(%esp),%eax                    /* load function pointer */
954                 movl    16(%esp),%ecx                   /* fourth argument *p */
955                 
956                 movl    %edx,%esp                               /* switch to new stack */
957
958                 subl    $4,%esp
959                 movl    %ecx,0(%esp)                    /* pass pointer */
960                 call    *%eax                                   /* and call function */
961                 addl    $4,%esp
962
963                 movl    (%esp),%edx                             /* load return address */
964                 movl    4(%esp),%esp                    /* switch to old stack */
965                 movl    %edx,(%esp)
966                 ret
967
968                 
969 /********************* function asm_getcallingmethod ***************************
970 *                                                                              *
971 *   classinfo *asm_getcallingmethod ();                                                                    *
972 *                                                                                                                                                          *    
973 *   goes back stack frames to get the calling method                                               *       
974 *                                                                                                                                                          *    
975 *                               t2 .. sp                                                                                                       *
976 *                               t3 .. ra                                                                                                       *
977 *                               t4 .. pv                                                                                                       *
978 *                                                                              *
979 *******************************************************************************/
980
981 asm_getcallingmethod:
982                 xorl    %eax,%eax
983 /*              movl    $0,(%eax) */
984                 ret
985
986
987 /*********************** function asm_builtin_trace ****************************
988 *                                                                              *
989 *   Intended to be called from the native stub. Saves all argument registers   *
990 *   and calls builtin_trace_args.                                              *
991 *                                                                              *
992 *******************************************************************************/
993
994 asm_builtin_trace:
995         pusha
996         subl    $68,%esp                /* 4 + 8 * 4 + 68 = 104 */
997
998         movl    104(%esp),%eax
999         movl    108(%esp),%edx
1000         movl    %eax,(%esp)
1001         movl    %edx,4(%esp)
1002
1003         movl    112(%esp),%eax
1004         movl    116(%esp),%edx
1005         movl    %eax,8(%esp)
1006         movl    %edx,12(%esp)
1007
1008         movl    120(%esp),%eax
1009         movl    124(%esp),%edx
1010         movl    %eax,16(%esp)
1011         movl    %edx,20(%esp)
1012
1013         movl    128(%esp),%eax
1014         movl    132(%esp),%edx
1015         movl    %eax,24(%esp)
1016         movl    %edx,28(%esp)
1017
1018         movl    136(%esp),%eax
1019         movl    140(%esp),%edx
1020         movl    %eax,32(%esp)
1021         movl    %edx,36(%esp)
1022
1023         movl    144(%esp),%eax
1024         movl    148(%esp),%edx
1025         movl    %eax,40(%esp)
1026         movl    %edx,44(%esp)
1027
1028         movl    152(%esp),%eax
1029         movl    156(%esp),%edx
1030         movl    %eax,48(%esp)
1031         movl    %edx,52(%esp)
1032
1033         movl    160(%esp),%eax
1034         movl    164(%esp),%edx
1035         movl    %eax,56(%esp)
1036         movl    %edx,60(%esp)
1037
1038         movl    168(%esp),%eax
1039         movl    %eax,64(%esp)
1040         
1041         call    builtin_trace_args
1042         addl    $68,%esp
1043
1044         popa
1045         ret
1046
1047
1048 /********************* function asm_builtin_exittrace **************************
1049 *                                                                              *
1050 *   Intended to be called from the native stub. Saves return value and calls   *
1051 *   builtin_displaymethodstop.                                                 *
1052 *                                                                              *
1053 *******************************************************************************/
1054
1055 asm_builtin_exittrace:
1056         pusha
1057         subl    $24,%esp
1058         
1059         movl    60(%esp),%eax           /* 4 + 8 * 4 + 24 = 60 */
1060         movl    %eax,(%esp)
1061
1062         movl    64(%esp),%eax
1063         movl    68(%esp),%edx
1064         movl    %eax,4(%esp)
1065         movl    %edx,8(%esp)
1066
1067         movl    72(%esp),%eax
1068         movl    76(%esp),%edx
1069         movl    %eax,12(%esp)
1070         movl    %edx,16(%esp)
1071
1072         movl    80(%esp),%eax
1073         movl    %eax,20(%esp)
1074
1075         call    builtin_displaymethodstop
1076         addl    $24,%esp
1077
1078         popa
1079         ret