Further enhancement, println() works!
[cacao.git] / i386 / asmpart.S
1 /* -*- mode: asm; tab-width: 4 -*- */
2 /****************************** asmpart.c **************************************
3 *                                                                              *
4 *   is an assembly language file, but called .c to fake the preprocessor.      *
5 *   It contains the Java-C interface functions for Alpha processors.           *
6 *                                                                              *
7 *   Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst              *
8 *                                                                              *
9 *   See file COPYRIGHT for information on usage and disclaimer of warranties   *
10 *                                                                              *
11 *   Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at            *
12 *            Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at            *
13 *                                                                              *
14 *   Last Change: 1998/11/01                                                    *
15 *                                                                              *
16 *******************************************************************************/
17
18 #include "offsets.h"
19
20         .text
21 /*      .set    noat */
22 /*      .set    noreorder */
23
24
25 /********************* exported functions and variables ***********************/
26
27         .globl has_no_x_instr_set
28         .globl synchronize_caches
29         .globl asm_calljavamethod
30         .globl asm_calljavafunction
31         .globl asm_call_jit_compiler
32         .globl asm_dumpregistersandcall
33         .globl asm_handle_exception
34         .globl asm_handle_nat_exception
35         .globl asm_builtin_checkcast    
36         .globl asm_builtin_checkarraycast
37         .globl asm_builtin_anewarray
38         .globl asm_builtin_aastore
39         .globl asm_builtin_monitorenter
40         .globl asm_builtin_monitorexit
41         .globl asm_builtin_idiv
42         .globl asm_builtin_irem
43         .globl asm_builtin_ldiv
44         .globl asm_builtin_lrem
45         .globl asm_perform_threadswitch
46         .globl asm_initialize_thread_stack
47         .globl asm_switchstackandcall
48         .globl asm_getcallingmethod
49
50 /*************************** imported variables *******************************/
51
52         .globl newcompiler
53
54
55 /*************************** imported functions *******************************/
56
57         .globl jit_compile
58         .globl builtin_monitorexit
59         .globl builtin_throw_exception
60         .globl builtin_trace_exception
61         .globl class_java_lang_Object
62
63
64 /*********************** function has_no_x_instr_set ***************************
65 *                                                                              *
66 *   determines if the byte support instruction set (21164a and higher)         *
67 *   is available.                                                              *
68 *                                                                              *
69 *******************************************************************************/
70
71 has_no_x_instr_set:
72
73 /*      .long   0x47e03c20                /* amask   1,v0                         */
74                 xorl    %eax, %eax
75 /*      jmp     zero,(ra)                 /* return                               */
76                 ret
77
78
79 /********************* function synchronize_caches ****************************/
80
81 synchronize_caches:
82
83 /*      call_pal PAL_imb                  /* synchronise instruction cache        */
84 /*      jmp     zero,(ra)                 /* return                               */
85                 ret
86
87
88 /********************* function asm_calljavamethod *****************************
89 *                                                                              *
90 *   This function calls a Java-method (which possibly needs compilation)       *
91 *   with up to 4 parameters.                                                   *
92 *                                                                              *
93 *   This functions calls the JIT-compiler which eventually translates the      *
94 *   method into machine code.                                                  *
95 *                                                                              *
96 *   An possibly throwed exception will be returned to the caller as function   *
97 *   return value, so the java method cannot return a fucntion value (this      *
98 *   function usually calls 'main' and '<clinit>' which do not return a         *
99 *   function value).                                                           *
100 *                                                                              *
101 *   C-prototype:                                                               *
102 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
103 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
104 *                                                                              *
105 *******************************************************************************/
106
107 #define         MethodPointer   -8
108 #define         FrameSize       -12
109 #define     IsSync          -16
110 #define     IsLeaf          -20
111 #define     IntSave         -24
112 #define     FltSave         -28
113 #define     ExTableSize     -32
114 #define     ExTableStart    -32
115
116 #define     ExEntrySize     -32
117 #define     ExStartPC       -8
118 #define     ExEndPC         -16
119 #define     ExHandlerPC     -24
120 #define     ExCatchType     -32
121
122 call_name:
123         .ascii  "calljavamethod\0\0"
124
125 /*      .align  3 */
126         .align  8
127         .quad   0                         /* catch type all                       */
128 /*      .quad   calljava_xhandler         /* handler pc                           */
129 /*      .quad   calljava_xhandler         /* end pc                               */
130 /*      .quad   asm_calljavamethod        /* start pc                             */
131         .long   1                         /* extable size                         */
132         .long   0                         /* fltsave                              */
133         .long   0                         /* intsave                              */
134         .long   0                         /* isleaf                               */
135         .long   0                         /* IsSync                               */
136         .long   32                        /* frame size                           */
137         .quad   0                         /* method pointer (pointer to name)     */
138
139 asm_calljavamethod:
140
141                 pushl   %ebp                  /* allocate stack space                 */
142                 movl    %esp, %ebp
143
144                 subl    $32,%esp              /* pass the remaining parameters        */
145                 xorl    %edx,%edx
146
147                 movl    %edx,28(%esp)         /* convert parms to 8 byte              */
148                 movl    24(%ebp),%eax
149                 movl    %eax,24(%esp)
150                 
151                 movl    %edx,20(%esp)
152                 movl    20(%ebp),%eax
153                 movl    %eax,16(%esp)
154
155                 movl    %edx,12(%esp)
156                 movl    16(%ebp),%eax
157                 movl    %eax,8(%esp)
158
159                 movl    %edx,4(%esp)
160                 movl    12(%ebp),%eax
161                 movl    %eax,(%esp)
162
163                 movl    8(%ebp),%eax          /* move function pointer to %eax        */
164
165 /*              pushl   %ebp                  /* save %ebp, cause it's a tmp reg      */
166                 
167                 call    asm_call_jit_compiler /* call JIT compiler                    */
168                 
169 /*              popl    %ebp                  /* restore %ebp, changed in java code   */
170                 
171 calljava_jit:
172 /*      lda     pv,-64(ra)                /* asm_calljavamethod-calljava_jit !!!!!*/
173
174 calljava_return:
175
176                 addl    $32,%esp              /* free stack space                     */
177                 
178 /*      ldl     v0,newcompiler            /* load newcompiler flag                */
179                 movl    newcompiler, %eax     /* load newcompiler flag                */
180 /*      subq    v0,1,v0                   /* negate for clearing v0               */
181                 subl    $1,%eax               /* negate for clearing v0               */
182 /*      beq     v0,calljava_ret           /* if newcompiler skip ex copying       */
183                 cmpl    $0,%eax               /* if newcompiler skip ex copying       */
184                 je      calljava_ret
185 /*      mov     $1,v0                     /* pass exception to caller (C)         */
186                 movl    $1, %eax              /* pass exception to caller (C)         */
187 calljava_ret:
188                 leave
189                 ret
190
191 calljava_xhandler:
192
193 /*      ldq     gp,24(sp)                 /* restore global pointer               */
194 /*      mov     itmp1,a0 */
195                 movl    $0,%eax
196 /*      jsr     ra,builtin_throw_exception */
197                 call    builtin_throw_exception
198 /*      ldq     ra,0(sp)                  /* restore return address               */
199 /*      lda     sp,32(sp)                 /* free stack space                     */
200 /*      jmp     zero,(ra) */
201                 leave
202                 ret
203
204
205 /********************* function asm_calljavafunction ***************************
206 *                                                                              *
207 *   This function calls a Java-method (which possibly needs compilation)       *
208 *   with up to 4 address parameters.                                           *
209 *                                                                              *
210 *   This functions calls the JIT-compiler which eventually translates the      *
211 *   method into machine code.                                                  *
212 *                                                                              *
213 *   C-prototype:                                                               *
214 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
215 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
216 *                                                                              *
217 *******************************************************************************/
218
219 call_name2:
220         .ascii  "calljavafunction\0\0"
221
222 /*      .align  3 */
223         .align  8
224         .quad   0                         /* catch type all                       */
225 /*      .quad   calljava_xhandler2        /* handler pc                           */
226 /*      .quad   calljava_xhandler2        /* end pc                               */
227 /*      .quad   asm_calljavafunction      /* start pc                             */
228         .long   1                         /* extable size                         */
229         .long   0                         /* fltsave                              */
230         .long   0                         /* intsave                              */
231         .long   0                         /* isleaf                               */
232         .long   0                         /* IsSync                               */
233         .long   32                        /* frame size                           */
234         .quad   0                         /* method pointer (pointer to name)     */
235
236 asm_calljavafunction:
237                 pushl   %ebp                  /* allocate stack space                 */
238                 movl    %esp, %ebp
239
240                 subl    $32,%esp              /* pass the remaining parameters        */
241                 xorl    %edx,%edx
242
243                 movl    %edx,28(%esp)         /* convert parms to 8 byte              */
244                 movl    24(%ebp),%eax
245                 movl    %eax,24(%esp)
246                 
247                 movl    %edx,20(%esp)
248                 movl    20(%ebp),%eax
249                 movl    %eax,16(%esp)
250
251                 movl    %edx,12(%esp)
252                 movl    16(%ebp),%eax
253                 movl    %eax,8(%esp)
254
255                 movl    %edx,4(%esp)
256                 movl    12(%ebp),%eax
257                 movl    %eax,(%esp)
258
259                 movl    8(%ebp),%eax          /* move function pointer to %eax        */
260
261 /*              pushl   %ebp                  /* save %ebp, cause it's a tmp reg      */
262                 
263                 call    asm_call_jit_compiler /* call JIT compiler                    */
264                 
265 /*              popl    %ebp                  /* restore %ebp, changed in java code   */
266                 
267 calljava_jit2:
268 /*      lda     pv,-64(ra)                /* asm_calljavamethod-calljava_jit !!!!!*/
269
270 calljava_return2:
271                 addl    $32,%esp              /* free stack space                     */
272                 
273 calljava_ret2:
274                 leave
275                 ret
276
277 calljava_xhandler2:
278
279 /*      ldq     gp,24(sp)                 /* restore global pointer               */
280 /*      mov     itmp1,a0 */
281                 movl    $0,%eax
282 /*      jsr     ra,builtin_throw_exception */
283                 call    builtin_throw_exception
284 /*      ldq     ra,0(sp)                  /* restore return address               */
285 /*      lda     sp,32(sp)                 /* free stack space                     */
286 /*      jmp     zero,(ra) */
287                 leave
288                 ret
289                                                 
290
291 /****************** function asm_call_jit_compiler *****************************
292 *                                                                              *
293 *   invokes the compiler for untranslated JavaVM methods.                      *
294 *                                                                              *
295 *   Register R0 contains a pointer to the method info structure (prepared      *
296 *   by createcompilerstub). Using the return address in R26 and the            *
297 *   offset in the LDA instruction or using the value in methodptr R28 the      *
298 *   patching address for storing the method address can be computed:           *
299 *                                                                              *
300 *   method address was either loaded using                                     *
301 *                                                                              *
302 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
303 *   i386_call_reg(REG_ITMP2)                                                   *
304 *                                                                              *
305 *   or                                                                         *
306 *                                                                              *
307 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
308 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
309 *   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
310 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
311 *   i386_call_reg(REG_ITMP1)                                                   *
312 *                                                                              *
313 *   in the static case the method pointer can be computed using the            *
314 *   return address and the lda function following the jmp instruction          *
315 *                                                                              *
316 *******************************************************************************/
317
318
319 asm_call_jit_compiler:
320
321                 pushl   %ebp
322                 movl    %esp, %ebp
323
324                 pushl   %eax                    /* push methodpointer on stack */
325                 call    jit_compile
326                 addl    $4,%esp
327
328                 movl    4(%ebp),%edx    /* get return address */
329                 movb    -1(%edx),%bl    /* get function code */
330                 cmpb    $0xd2,%bl               /* called with `call *REG_ITMP2' (%edx)? */
331                 jne             L01
332
333                 subl    $6,%edx                 /* calculate address of immediate */
334                 movl    %eax,(%edx)             /* and now save the new pointer */
335
336 L01:    leave
337                 jmp             *%eax                   /* ...and now call the new method */
338
339
340
341 /****************** function asm_dumpregistersandcall **************************
342 *                                                                              *
343 *   This funtion saves all callee saved registers and calls the function       *
344 *   which is passed as parameter.                                              *
345 *                                                                              *
346 *   This function is needed by the garbage collector, which needs to access    *
347 *   all registers which are stored on the stack. Unused registers are          *
348 *   cleared to avoid interferances with the GC.                                *
349 *                                                                              *
350 *   void asm_dumpregistersandcall (functionptr f);                             *
351 *                                                                              *
352 *******************************************************************************/
353
354 asm_dumpregistersandcall:
355         pushl   %ebp                            /* build stack frame */
356         movl    %esp,%ebp
357                 
358         movl    8(%ebp),%eax            /* load function pointer */
359         call    *%eax                           /* call function */
360
361         leave
362         ret
363
364
365 /********************* function asm_handle_exception ***************************
366 *                                                                              *
367 *   This function handles an exception. It does not use the usual calling      *
368 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
369 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
370 *   the local exception table for a handler. If no one is found, it unwinds    *
371 *   stacks and continues searching the callers.                                *
372 *                                                                              *
373 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
374 *                                                                              *
375 *******************************************************************************/
376
377 asm_handle_nat_exception:
378 asm_handle_exception:
379         xorl            %eax,%eax
380         movl            $0,(%eax)
381         ret
382
383
384 /********************* function asm_builtin_monitorenter ***********************
385 *                                                                              *
386 *   Does null check and calls monitorenter or throws an exception              *
387 *                                                                              *
388 *******************************************************************************/
389
390 asm_builtin_monitorenter:
391         jmp             builtin_monitorenter
392
393
394 /********************* function asm_builtin_monitorexit ************************
395 *                                                                              *
396 *   Does null check and calls monitorexit or throws an exception               *
397 *                                                                              *
398 *******************************************************************************/
399
400 asm_builtin_monitorexit:
401         jmp             builtin_monitorexit
402
403
404 /************************ function asm_builtin_idiv ****************************
405 *                                                                              *
406 *   Does null check and calls idiv or throws an exception                      *
407 *                                                                              *
408 *******************************************************************************/
409
410 asm_builtin_idiv:
411         ret
412                 
413
414 /************************ function asm_builtin_ldiv ****************************
415 *                                                                              *
416 *   Does null check and calls ldiv or throws an exception                      *
417 *                                                                              *
418 *******************************************************************************/
419
420 asm_builtin_ldiv:
421         jmp             builtin_ldiv
422                                 
423
424 /************************ function asm_builtin_irem ****************************
425 *                                                                              *
426 *   Does null check and calls irem or throws an exception                      *
427 *                                                                              *
428 *******************************************************************************/
429
430 asm_builtin_irem:
431         ret
432
433
434 /************************ function asm_builtin_lrem ****************************
435 *                                                                              *
436 *   Does null check and calls lrem or throws an exception                      *
437 *                                                                              *
438 *******************************************************************************/
439
440 asm_builtin_lrem:
441         jmp             builtin_lrem
442                 
443
444 /*********************** function new_builtin_checkcast ************************
445 *                                                                              *
446 *   Does the cast check and eventually throws an exception                     *
447 *                                                                              *
448 *******************************************************************************/
449
450 asm_builtin_checkcast:
451         xorl            %eax,%eax
452         movl            $0,(%eax)
453         ret
454
455                 
456 /******************* function asm_builtin_checkarraycast ***********************
457 *                                                                              *
458 *   Does the cast check and eventually throws an exception                     *
459 *                                                                              *
460 *******************************************************************************/
461
462 asm_builtin_checkarraycast:
463         subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
464
465         movl    12(%esp),%eax
466         movl    %eax,(%esp)
467
468         movl    20(%esp),%eax
469         movl    %eax,4(%esp)
470
471         call    builtin_checkarraycast
472         
473         addl    $8,%esp
474         ret
475                 
476
477 /******************* function asm_builtin_anewarray ****************************
478 *                                                                              *
479 *   Does the cast check and eventually throws an exception                     *
480 *                                                                              *
481 *******************************************************************************/
482
483 asm_builtin_anewarray:
484         subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
485
486         movl    12(%esp),%eax
487         movl    %eax,(%esp)
488
489         movl    20(%esp),%eax
490         movl    %eax,4(%esp)
491
492         call    builtin_anewarray
493         
494         addl    $8,%esp
495         ret
496
497
498 /******************* function asm_builtin_aastore ******************************
499 *                                                                              *
500 *   Does the cast check and eventually throws an exception                     *
501 *                                                                              *
502 *******************************************************************************/
503
504 asm_builtin_aastore:
505         subl    $12,%esp                        /* build stack frame (3 * 4 bytes) */
506
507         movl    16(%esp),%eax
508         movl    %eax,(%esp)
509
510         movl    24(%esp),%eax
511         movl    %eax,4(%esp)
512
513         movl    32(%esp),%eax
514         movl    %eax,8(%esp)
515                 
516         call    builtin_aastore
517         
518         addl    $12,%esp
519         ret
520
521
522 /******************* function asm_initialize_thread_stack **********************
523 *                                                                              *
524 *   initialized a thread stack                                                 *
525 *                                                                              *
526 *******************************************************************************/
527
528 asm_initialize_thread_stack:
529         xorl            %eax,%eax
530         movl            $0,(%eax)
531         ret
532
533
534 /******************* function asm_perform_threadswitch *************************
535 *                                                                              *
536 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
537 *                                                                              *
538 *   performs a threadswitch                                                    *
539 *                                                                              *
540 *******************************************************************************/
541
542 asm_perform_threadswitch:
543         xorl            %eax,%eax
544         movl            $0,(%eax)
545         ret
546                 
547
548 /********************* function asm_switchstackandcall *************************
549 *                                                                              *
550 *  void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
551 *                                                                              *
552 *   Switches to a new stack, calls a function and switches back.               *
553 *       a0      new stack pointer                                              *
554 *       a1      function pointer                                               *
555 *               a2              pointer to variable where stack top should be stored           *
556 *                                                                              *
557 *******************************************************************************/
558
559 asm_switchstackandcall:
560         xorl            %eax,%eax
561         movl            $0,(%eax)
562         ret
563
564                 
565 /********************* function asm_getcallingmethod ***************************
566 *                                                                              *
567 *   classinfo *asm_getcallingmethodclass ();                                                               *
568 *                                                                                                                                                          *    
569 *   goes back stack frames to get the calling method                                               *       
570 *                                                                                                                                                          *    
571 *                               t2 .. sp                                                                                                       *
572 *                               t3 .. ra                                                                                                       *
573 *                               t4 .. pv                                                                                                       *
574 *                                                                              *
575 *******************************************************************************/
576
577 asm_getcallingmethod:
578         xorl            %eax,%eax
579         movl            $0,(%eax)
580         ret