* src/vm/hashtable.h,
[cacao.git] / src / vm / jit / alpha / asmpart.S
1 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29
30    Changes: Joseph Wenninger
31             Christian Thalinger
32                 Edwin Steiner
33
34    $Id: asmpart.S 4921 2006-05-15 14:24:36Z twisti $
35
36 */
37
38
39 #include "config.h"
40
41 #include "vm/jit/alpha/md-abi.h"
42 #include "vm/jit/alpha/md-asm.h"
43 #include "vm/jit/alpha/offsets.h"
44
45 #include "vm/jit/abi-asm.h"
46 #include "vm/jit/methodheader.h"
47
48
49         .text
50         .set    noat
51         .set    noreorder
52
53
54 /* export functions ***********************************************************/
55
56         .globl asm_vm_call_method
57         .globl asm_vm_call_method_int
58         .globl asm_vm_call_method_long
59         .globl asm_vm_call_method_float
60         .globl asm_vm_call_method_double
61         .globl asm_vm_call_method_exception_handler
62
63         .globl asm_call_jit_compiler
64         .globl asm_handle_exception
65         .globl asm_handle_nat_exception
66
67         .globl asm_wrapper_patcher
68
69         .globl asm_replacement_out
70         .globl asm_replacement_in
71
72         .globl asm_perform_threadswitch
73         .globl asm_initialize_thread_stack
74         .globl asm_switchstackandcall
75         .globl asm_criticalsections
76         .globl asm_getclassvalues_atomic
77
78         .globl asm_md_init
79         .globl asm_cacheflush
80
81
82 /* asm_vm_call_method **********************************************************
83 *                                                                              *
84 *   This function calls a Java-method (which possibly needs compilation)       *
85 *   with up to 4 address parameters.                                           *
86 *                                                                              *
87 *   This functions calls the JIT-compiler which eventually translates the      *
88 *   method into machine code.                                                  *
89 *                                                                              *
90 *   C-prototype:                                                               *
91 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
92 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
93 *                                                                              *
94 *******************************************************************************/
95
96         .ent    asm_vm_call_method
97
98         .align  3
99
100         .quad   0                           /* catch type all                     */
101         .quad   0                           /* handler pc                         */
102         .quad   0                           /* end pc                             */
103         .quad   0                           /* start pc                           */
104         .long   1                           /* extable size                       */
105         .long   0                           /* ALIGNMENT PADDING                  */
106         .quad   0                           /* line number table start            */
107         .quad   0                           /* line number table size             */
108         .long   0                           /* ALIGNMENT PADDING                  */
109         .long   0                           /* fltsave                            */
110         .long   1                           /* intsave                            */
111         .long   0                           /* isleaf                             */
112         .long   0                           /* IsSync                             */
113         .long   0                           /* frame size                         */
114         .quad   0                           /* method pointer (pointer to name)   */
115
116 asm_vm_call_method:
117 asm_vm_call_method_int:
118 asm_vm_call_method_long:
119 asm_vm_call_method_float:
120 asm_vm_call_method_double:
121         ldgp    gp,0(pv)
122         lda     sp,-5*8(sp)               /* allocate stack space                 */
123         stq     ra,0*8(sp)                /* save return address                  */
124         stq     gp,1*8(sp)                /* save global pointer                  */
125         stq     s6,3*8(sp)
126
127         stq     a0,4*8(sp)                /* save method pointer for compiler     */
128
129         mov     a2,t0                     /* pointer to arg block                 */
130         mov     a1,s6                     /* arg count                            */
131
132         ble     s6,calljava_argsloaded
133         lda     s6,-1(s6)
134         ldq     a0,offvmargdata(t0)
135         ldt     $f16,offvmargdata(t0)
136         ble     s6,calljava_argsloaded
137
138         lda     s6,-1(s6)
139         ldq     a1,offvmargdata+sizevmarg*1(t0)
140         ldt     $f17,offvmargdata+sizevmarg*1(t0)
141         ble     s6,calljava_argsloaded
142
143         lda     s6,-1(s6)
144         ldq     a2,offvmargdata+sizevmarg*2(t0)
145         ldt     $f18,offvmargdata+sizevmarg*2(t0)
146         ble     s6,calljava_argsloaded
147
148         lda     s6,-1(s6)
149         ldq     a3,offvmargdata+sizevmarg*3(t0)
150         ldt     $f19,offvmargdata+sizevmarg*3(t0)
151         ble     s6,calljava_argsloaded
152
153         lda     s6,-1(s6)
154         ldq     a4,offvmargdata+sizevmarg*4(t0)
155         ldt     $f20,offvmargdata+sizevmarg*4(t0)
156         ble     s6,calljava_argsloaded
157
158         lda     s6,-1(s6)
159         ldq     a5,offvmargdata+sizevmarg*5(t0)
160         ldt     $f21,offvmargdata+sizevmarg*5(t0)
161 calljava_argsloaded:
162         mov     sp,t4
163         ble     s6,calljava_nocopy
164         negq    s6,t1
165         s8addq  t1,sp,sp
166         s8addq  t1,t4,t2
167
168 calljava_copyloop:
169         ldq     t3,offvmargdata+sizevmarg*6(t0)
170         stq     t3,0(t2)
171         lda     t1,1(t1)
172         lda     t0,sizevmarg(t0)
173         lda     t2,8(t2)
174         bne     t1,calljava_copyloop
175
176 calljava_nocopy:
177         ldq     itmp1,4*8(t4)             /* pass method pointer via itmp1        */
178
179         lda     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
180         stq     mptr,2*8(t4)              /* store function address               */
181         lda     mptr,1*8(t4)              /* set method pointer                   */
182
183         ldq     pv,1*8(mptr)              /* method call as in Java               */
184         jmp     ra,(pv)                   /* call JIT compiler                    */
185 calljava_jit2:
186         lda     pv,(asm_vm_call_method - calljava_jit2)(ra)
187
188         s8addq  s6,sp,sp
189 calljava_return2:
190         ldq     ra,0*8(sp)                /* restore return address               */
191         ldq     gp,1*8(sp)                /* restore global pointer               */
192         ldq     s6,3*8(sp)
193         lda     sp,5*8(sp)                /* free stack space                     */
194
195 calljava_ret2:
196         jmp     zero,(ra)
197
198 asm_vm_call_method_exception_handler:
199         s8addq  s6,sp,sp
200         ldq     gp,1*8(sp)                /* restore global pointer               */
201         mov     itmp1,a0
202         jsr     ra,builtin_throw_exception
203         ldq     ra,0*8(sp)                /* restore return address               */
204         ldq     s6,3*8(sp)
205         lda     sp,5*8(sp)                /* free stack space                     */
206         jmp     zero,(ra)
207
208         .end    asm_vm_call_method
209
210
211 /* asm_call_jit_compiler *******************************************************
212
213    Invokes the compiler for untranslated Java methods.
214
215 *******************************************************************************/
216
217         .ent    asm_call_jit_compiler
218
219 asm_call_jit_compiler:
220         ldgp    gp,0(pv)
221         lda     sp,-(ARG_CNT+2)*8(sp) /* +2: keep stack 16-byte aligned           */
222
223         stq     ra,0*8(sp)            /* save return address                      */
224
225         SAVE_ARGUMENT_REGISTERS(1)    /* save 6 int/6 float argument registers    */
226
227         mov     itmp1,a0              /* pass methodinfo pointer                  */
228         mov     mptr,a1               /* pass method pointer                      */
229         lda     a2,(ARG_CNT+2)*8(sp)  /* pass java sp                             */
230         mov     ra,a3
231         jsr     ra,jit_asm_compile    /* call jit compiler                        */
232         mov     v0,pv
233
234         ldq     ra,0*8(sp)            /* load return address                      */
235
236         RESTORE_ARGUMENT_REGISTERS(1) /* restore 6 int/6 float argument registers */
237
238         lda     sp,(ARG_CNT+2)*8(sp)  /* remove stack frame                       */
239
240         beq     pv,L_asm_call_jit_compiler_exception
241
242         jmp     zero,(pv)             /* and call method, the method returns      */
243                                       /* directly to the caller (ra).             */
244
245 L_asm_call_jit_compiler_exception:
246 #if defined(ENABLE_THREADS)
247         subq    sp,2*8,sp
248         stq     ra,0*8(sp)            /* save return address (xpc)                */
249         jsr     ra,builtin_asm_get_exceptionptrptr
250         ldq     ra,0*8(sp)            /* restore return address (xpc)             */
251         addq    sp,2*8,sp
252 #else
253         lda     v0,_exceptionptr
254 #endif
255         ldq     xptr,0(v0)            /* get the exception pointer                */
256         stq     zero,0(v0)            /* clear the exception pointer              */
257
258         subq    ra,4,xpc
259         br      L_asm_handle_nat_exception
260
261         .end    asm_call_jit_compiler
262
263
264 /* asm_handle_exception ********************************************************
265
266    This function handles an exception. It does not use the usual calling
267    conventions. The exception pointer is passed in REG_ITMP1 and the
268    pc from the exception raising position is passed in REG_ITMP2. It searches
269    the local exception table for a handler. If no one is found, it unwinds
270    stacks and continues searching the callers.
271
272    ATTENTION: itmp3 == gp!
273
274 *******************************************************************************/
275
276         .ent    asm_handle_nat_exception
277
278 asm_handle_nat_exception:
279 L_asm_handle_nat_exception:       /* required for PIC code                    */
280         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
281         sll     t0,48,t0
282         sra     t0,48,t0              /* isolate offset                           */
283         addq    t0,ra,pv              /* compute update address                   */
284         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
285         srl     t0,16,t0              /* isolate instruction code                 */
286         lda     t0,-0x177b(t0)        /* test for LDAH                            */
287         bne     t0,L_asm_handle_exception
288         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
289         sll     t0,16,t0              /* compute high offset                      */
290         addl    t0,0,t0               /* sign extend high offset                  */
291         addq    t0,pv,pv              /* compute update address                   */
292
293         .aent    asm_handle_exception
294
295 asm_handle_exception:
296 L_asm_handle_exception:                 /* required for PIC code              */
297         lda     sp,-(ARG_CNT+TMP_CNT)*8(sp) /* create maybe-leaf stackframe       */
298
299         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
300         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
301
302         lda     a3,(ARG_CNT+TMP_CNT)*8(zero)/* prepare a3 for handle_exception */
303         lda     a4,1(zero)                  /* set maybe-leaf flag                */
304
305 L_asm_handle_exception_stack_loop:
306         lda     sp,-5*8(sp)                 /* allocate stack                     */
307         stq     xptr,0*8(sp)                /* save exception pointer             */
308         stq     xpc,1*8(sp)                 /* save exception pc                  */
309         stq     pv,2*8(sp)                  /* save data segment pointer          */
310         stq     ra,3*8(sp)                  /* save return address                */
311         addq    a3,sp,a3                    /* calculate Java sp into a3...       */
312         addq    a3,5*8,a3
313         stq     a4,4*8(sp)                  /* save maybe-leaf flag               */
314
315         br      ra,L_asm_handle_exception_load_gp /* set ra for gp loading        */
316 L_asm_handle_exception_load_gp:
317         ldgp    gp,0(ra)                    /* load gp                            */
318
319         mov     xptr,a0                     /* pass exception pointer             */
320         mov     xpc,a1                      /* pass exception pc                  */
321         mov     pv,a2                       /* pass data segment pointer          */
322                                             /* a3 is still set                    */
323         jsr     ra,exceptions_handle_exception
324
325         beq     v0,L_asm_handle_exception_not_catched
326
327         mov     v0,xpc                      /* move handlerpc into xpc            */
328         ldq     xptr,0*8(sp)                /* restore exception pointer          */
329         ldq     pv,2*8(sp)                  /* restore data segment pointer       */
330         ldq     ra,3*8(sp)                  /* restore return address             */
331         ldq     a4,4*8(sp)                  /* get maybe-leaf flag                */
332         lda     sp,5*8(sp)                  /* free stack frame                   */
333
334         beq     a4,L_asm_handle_exception_no_leaf
335
336         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
337         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
338         
339         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
340
341 L_asm_handle_exception_no_leaf:
342         jmp     zero,(xpc)                  /* jump to the handler                */
343
344 L_asm_handle_exception_not_catched:
345         ldq     xptr,0*8(sp)                /* restore exception pointer          */
346         ldq     pv,2*8(sp)                  /* restore data segment pointer       */
347         ldq     ra,3*8(sp)                  /* restore return address             */
348         ldq     a4,4*8(sp)                  /* get maybe-leaf flag                */
349         lda     sp,5*8(sp)
350
351         beq     a4,L_asm_handle_exception_no_leaf_stack
352
353         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
354         mov     zero,a4                     /* clear the maybe-leaf flag          */
355
356 L_asm_handle_exception_no_leaf_stack:
357         ldl     t0,FrameSize(pv)            /* get frame size                     */
358         addq    t0,sp,t0                    /* pointer to save area               */
359
360         ldl     t1,IsLeaf(pv)               /* is leaf procedure                  */
361         bne     t1,L_asm_handle_exception_no_ra_restore
362
363         ldq     ra,-1*8(t0)                 /* restore ra                         */
364         subq    t0,8,t0                     /* t0--                               */
365
366 L_asm_handle_exception_no_ra_restore:
367         mov     ra,xpc                      /* the new xpc is ra                  */
368         ldl     t1,IntSave(pv)              /* t1 = saved int register count      */
369         br      t2,ex_int1                  /* t2 = current pc                    */
370 ex_int1:
371         lda     t2,(ex_int2-ex_int1)(t2)
372         negl    t1,t1                       /* negate register count              */
373         s4addq  t1,t2,t2                    /* t2 = IntSave - register count * 4  */
374         jmp     zero,(t2)                   /* jump to save position              */
375
376         ldq     s0,-7*8(t0)
377         ldq     s1,-6*8(t0)
378         ldq     s2,-5*8(t0)
379         ldq     s3,-4*8(t0)
380         ldq     s4,-3*8(t0)
381         ldq     s5,-2*8(t0)
382         ldq     s6,-1*8(t0)
383
384 ex_int2:
385         s8addq  t1,t0,t0                    /* t0 = t0 - 8 * register count       */
386
387         ldl     t1,FltSave(pv)              /* t1 = saved flt register count      */
388         br      t2,ex_flt1                  /* t2 = current pc                    */
389 ex_flt1:
390         lda     t2,(ex_flt2-ex_flt1)(t2)
391         negl    t1,t1                       /* negate register count              */
392         s4addq  t1,t2,t2                    /* t2 = FltSave - 4 * register count  */
393         jmp     zero,(t2)                   /* jump to save position              */
394
395         ldt     fs0,-8*8(t0)
396         ldt     fs1,-7*8(t0)
397         ldt     fs2,-6*8(t0)
398         ldt     fs3,-5*8(t0)
399         ldt     fs4,-4*8(t0)
400         ldt     fs5,-3*8(t0)
401         ldt     fs6,-2*8(t0)
402         ldt     fs7,-1*8(t0)
403
404 ex_flt2:
405         ldl     t0,FrameSize(pv)            /* get frame size                     */
406         addq    sp,t0,sp                    /* unwind stack                       */
407         mov     zero,a3                     /* prepare a3 for handle_exception    */
408
409         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
410         sll     t0,48,t0
411         sra     t0,48,t0              /* isolate offset                           */
412         addq    t0,ra,pv              /* compute update address                   */
413         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
414         srl     t0,16,t0              /* isolate instruction code                 */
415         lda     t0,-0x177b(t0)        /* test for LDAH                            */
416         bne     t0,L_asm_handle_exception_stack_loop
417         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
418         sll     t0,16,t0              /* compute high offset                      */
419         addl    t0,0,t0               /* sign extend high offset                  */
420         addq    t0,pv,pv              /* compute update address                   */
421
422         br      L_asm_handle_exception_stack_loop
423
424         .end    asm_handle_nat_exception
425
426
427 /* asm_wrapper_patcher *********************************************************
428
429    XXX
430
431    Stack layout:
432      40   return address into JIT code (patch position)
433      32   pointer to virtual java_objectheader
434      24   machine code (which is patched back later)
435      16   unresolved class/method/field reference
436       8   data segment displacement from load instructions
437       0   patcher function pointer to call (pv afterwards)
438
439    ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
440
441 *******************************************************************************/
442                 
443         .ent    asm_wrapper_patcher
444
445 asm_wrapper_patcher:
446         lda     sp,-((2+12+27+4)*8+sizestackframeinfo)(sp) /* create stack frame  */
447
448         SAVE_RETURN_REGISTERS(0)      /* save 1 int/1 float return registers      */
449         SAVE_ARGUMENT_REGISTERS(2)    /* save 6 int/6 float argument registers    */
450         SAVE_TEMPORARY_REGISTERS(14)  /* save 11 int/16 float temporary registers */
451
452         stq     itmp1,(2+12+27+0)*8(sp) /* save itmp1                             */
453         stq     itmp2,(2+12+27+1)*8(sp) /* save itmp2                             */
454         stq     ra,(2+12+27+2)*8(sp)  /* save method return address (for leafs)   */
455         stq     pv,(2+12+27+3)*8(sp)  /* save pv of calling java function         */
456
457         br      ra,L_asm_wrapper_patcher_load_gp
458 L_asm_wrapper_patcher_load_gp:
459         ldgp    gp,0(ra)              /* load gp (it's not set correctly in jit)  */
460
461         lda     a0,(2+12+27+4)*8(sp)  /* create stackframe info                   */
462         mov     pv,a1                 /* pass java pv                             */
463         lda     a2,((6+2+12+27+4)*8+sizestackframeinfo)(sp) /* pass java sp       */
464         ldq     a3,(2+12+27+2)*8(sp)  /* this is correct for leafs                */
465         ldq     a4,((5+2+12+27+4)*8+sizestackframeinfo)(sp) /* pass xpc           */
466         jsr     ra,stacktrace_create_extern_stackframeinfo
467         ldgp    gp,0(ra)
468
469         lda     a0,((0+2+12+27+4)*8+sizestackframeinfo)(sp) /* pass sp            */
470         ldq     pv,((0+2+12+27+4)*8+sizestackframeinfo)(sp) /* get function       */
471         ldq     itmp1,(2+12+27+3)*8(sp) /* save pv to the position of fp          */
472         stq     itmp1,((0+2+12+27+4)*8+sizestackframeinfo)(sp)
473         jmp     ra,(pv)               /* call the patcher function                */
474         ldgp    gp,0(ra)
475         stq     v0,((0+2+12+27+4)*8+sizestackframeinfo)(sp) /* save return value  */
476
477         lda     a0,(2+12+27+4)*8(sp)  /* remove stackframe info                   */
478         jsr     ra,stacktrace_remove_stackframeinfo
479         ldgp    gp,0(ra)
480
481         RESTORE_RETURN_REGISTERS(0)   /* restore 1 int/1 float return registers   */
482         RESTORE_ARGUMENT_REGISTERS(2) /* restore 6 int/6 float argument registers */
483         RESTORE_TEMPORARY_REGISTERS(14) /* restore 11 integer temporary registers */
484
485         ldq     itmp1,(2+12+27+0)*8(sp) /* restore itmp1                          */
486         ldq     itmp2,(2+12+27+1)*8(sp) /* restore itmp2                          */
487         ldq     ra,(2+12+27+2)*8(sp)  /* restore method return address (for leafs)*/
488         ldq     pv,(2+12+27+3)*8(sp)  /* restore pv of calling java function      */
489
490         ldq     itmp3,((0+2+12+27+4)*8+sizestackframeinfo)(sp) /* get return value*/
491         beq     itmp3,L_asm_wrapper_patcher_exception
492
493         ldq     itmp3,((5+2+12+27+4)*8+sizestackframeinfo)(sp)/* get RA to JIT    */
494         lda     sp,((6+2+12+27+4)*8+sizestackframeinfo)(sp) /* remove stack frame */
495
496         jmp     zero,(itmp3)          /* jump to new patched code                 */
497
498 L_asm_wrapper_patcher_exception:
499         ldq     xpc,((5+2+12+27+4)*8+sizestackframeinfo)(sp) /* RA is xpc         */
500         lda     sp,((6+2+12+27+4)*8+sizestackframeinfo)(sp) /* remove stack frame */
501
502         br      itmp1,L_asm_wrapper_patcher_exception_load_gp
503 L_asm_wrapper_patcher_exception_load_gp:
504         ldgp    gp,0(itmp1)           /* itmp3 == gp, load the current gp         */
505
506 #if defined(ENABLE_THREADS)
507         subq    sp,3*8,sp
508         stq     xpc,0*8(sp)           /* save return address (xpc)                */
509         stq     ra,1*8(sp)
510         stq     pv,2*8(sp)
511         jsr     ra,builtin_asm_get_exceptionptrptr
512         ldq     xpc,0*8(sp)           /* restore return address (xpc)             */
513         ldq     ra,1*8(sp)
514         ldq     pv,2*8(sp)
515         addq    sp,3*8,sp
516 #else
517         lda     v0,_exceptionptr
518 #endif
519         ldq     xptr,0(v0)            /* get the exception pointer                */
520         stq     zero,0(v0)            /* clear the exception pointer              */
521         br      L_asm_handle_exception/* we have the pv of the calling java func. */
522
523         .end    asm_wrapper_patcher
524
525                 
526 /* asm_replacement_out *********************************************************
527
528    This code is jumped to from the replacement-out stubs that are executed
529    when a thread reaches an activated replacement point.
530
531    The purpose of asm_replacement_out is to read out the parts of the
532    execution state that cannot be accessed from C code, store this state,
533    and then call the C function replace_me.
534
535    Stack layout:
536      16                 start of stack inside method to replace
537       0   rplpoint *    info on the replacement point that was reached
538
539    NOTE: itmp3 has been clobbered by the replacement-out stub!
540
541 *******************************************************************************/
542
543 /* some room to accomodate changes of the stack frame size during replacement */
544         /* XXX we should find a cleaner solution here */
545 #define REPLACEMENT_ROOM  512
546
547 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
548
549         .ent asm_replacement_out
550
551 asm_replacement_out:
552     /* create stack frame */
553         lda     sp,-(REPLACEMENT_STACK_OFFSET)(sp)
554
555         /* save registers in execution state */
556         stq     $0 ,( 0*8+offes_intregs)(sp)
557         stq     $1 ,( 1*8+offes_intregs)(sp)
558         stq     $2 ,( 2*8+offes_intregs)(sp)
559         stq     $3 ,( 3*8+offes_intregs)(sp)
560         stq     $4 ,( 4*8+offes_intregs)(sp)
561         stq     $5 ,( 5*8+offes_intregs)(sp)
562         stq     $6 ,( 6*8+offes_intregs)(sp)
563         stq     $7 ,( 7*8+offes_intregs)(sp)
564         stq     $8 ,( 8*8+offes_intregs)(sp)
565         stq     $9 ,( 9*8+offes_intregs)(sp)
566         stq     $10,(10*8+offes_intregs)(sp)
567         stq     $11,(11*8+offes_intregs)(sp)
568         stq     $12,(12*8+offes_intregs)(sp)
569         stq     $13,(13*8+offes_intregs)(sp)
570         stq     $14,(14*8+offes_intregs)(sp)
571         stq     $15,(15*8+offes_intregs)(sp)
572         stq     $16,(16*8+offes_intregs)(sp)
573         stq     $17,(17*8+offes_intregs)(sp)
574         stq     $18,(18*8+offes_intregs)(sp)
575         stq     $19,(19*8+offes_intregs)(sp)
576         stq     $20,(20*8+offes_intregs)(sp)
577         stq     $21,(21*8+offes_intregs)(sp)
578         stq     $22,(22*8+offes_intregs)(sp)
579         stq     $23,(23*8+offes_intregs)(sp)
580         stq     $24,(24*8+offes_intregs)(sp)
581         stq     $25,(25*8+offes_intregs)(sp)
582         stq     $26,(26*8+offes_intregs)(sp)
583         stq     $27,(27*8+offes_intregs)(sp)
584         stq     $28,(28*8+offes_intregs)(sp)
585         stq     $29,(29*8+offes_intregs)(sp)
586         stq     $30,(30*8+offes_intregs)(sp)
587         stq     $31,(31*8+offes_intregs)(sp)
588         
589         stt     $f0 ,( 0*8+offes_fltregs)(sp)
590         stt     $f1 ,( 1*8+offes_fltregs)(sp)
591         stt     $f2 ,( 2*8+offes_fltregs)(sp)
592         stt     $f3 ,( 3*8+offes_fltregs)(sp)
593         stt     $f4 ,( 4*8+offes_fltregs)(sp)
594         stt     $f5 ,( 5*8+offes_fltregs)(sp)
595         stt     $f6 ,( 6*8+offes_fltregs)(sp)
596         stt     $f7 ,( 7*8+offes_fltregs)(sp)
597         stt     $f8 ,( 8*8+offes_fltregs)(sp)
598         stt     $f9 ,( 9*8+offes_fltregs)(sp)
599         stt     $f10,(10*8+offes_fltregs)(sp)
600         stt     $f11,(11*8+offes_fltregs)(sp)
601         stt     $f12,(12*8+offes_fltregs)(sp)
602         stt     $f13,(13*8+offes_fltregs)(sp)
603         stt     $f14,(14*8+offes_fltregs)(sp)
604         stt     $f15,(15*8+offes_fltregs)(sp)
605         stt     $f16,(16*8+offes_fltregs)(sp)
606         stt     $f17,(17*8+offes_fltregs)(sp)
607         stt     $f18,(18*8+offes_fltregs)(sp)
608         stt     $f19,(19*8+offes_fltregs)(sp)
609         stt     $f20,(20*8+offes_fltregs)(sp)
610         stt     $f21,(21*8+offes_fltregs)(sp)
611         stt     $f22,(22*8+offes_fltregs)(sp)
612         stt     $f23,(23*8+offes_fltregs)(sp)
613         stt     $f24,(24*8+offes_fltregs)(sp)
614         stt     $f25,(25*8+offes_fltregs)(sp)
615         stt     $f26,(26*8+offes_fltregs)(sp)
616         stt     $f27,(27*8+offes_fltregs)(sp)
617         stt     $f28,(28*8+offes_fltregs)(sp)
618         stt     $f29,(29*8+offes_fltregs)(sp)
619         stt     $f30,(30*8+offes_fltregs)(sp)
620         stt     $f31,(31*8+offes_fltregs)(sp)
621         
622         /* calculate sp of method */
623         lda     itmp1,(REPLACEMENT_STACK_OFFSET + 2*8)(sp)
624         stq     itmp1,(offes_sp)(sp)
625
626         br      ra,L_asm_replacement_out_load_gp
627 L_asm_replacement_out_load_gp:
628         ldgp    gp,0(ra)                    /* load gp                            */
629
630         /* store pv */
631         stq     pv,(offes_pv)(sp)
632
633         /* call replace_me */
634         ldq     a0,-(2*8)(itmp1)            /* arg0: rplpoint *                   */
635     mov     sp,a1                       /* arg1: execution state              */
636     jmp     zero,replace_me             /* call C function replace_me         */
637     jmp     zero,abort                  /* NEVER REACHED                      */
638
639         .end asm_replacement_out
640
641 /* asm_replacement_in **********************************************************
642
643    This code writes the given execution state and jumps to the replacement
644    code.
645
646    This function never returns!
647
648    NOTE: itmp3 is not restored!
649
650    C prototype:
651       void asm_replacement_in(executionstate *es);
652
653 *******************************************************************************/
654
655         .ent asm_replacement_in
656         
657 asm_replacement_in:
658         /* a0 == executionstate *es */
659
660         /* set new sp and pv */
661         ldq     sp,(offes_sp)(a0)
662         ldq     pv,(offes_pv)(a0)
663         
664         /* copy registers from execution state */
665         ldq     $0 ,( 0*8+offes_intregs)(a0)
666         ldq     $1 ,( 1*8+offes_intregs)(a0)
667         ldq     $2 ,( 2*8+offes_intregs)(a0)
668         ldq     $3 ,( 3*8+offes_intregs)(a0)
669         ldq     $4 ,( 4*8+offes_intregs)(a0)
670         ldq     $5 ,( 5*8+offes_intregs)(a0)
671         ldq     $6 ,( 6*8+offes_intregs)(a0)
672         ldq     $7 ,( 7*8+offes_intregs)(a0)
673         ldq     $8 ,( 8*8+offes_intregs)(a0)
674         ldq     $9 ,( 9*8+offes_intregs)(a0)
675         ldq     $10,(10*8+offes_intregs)(a0)
676         ldq     $11,(11*8+offes_intregs)(a0)
677         ldq     $12,(12*8+offes_intregs)(a0)
678         ldq     $13,(13*8+offes_intregs)(a0)
679         ldq     $14,(14*8+offes_intregs)(a0)
680         ldq     $15,(15*8+offes_intregs)(a0)
681         /* a0 is loaded below             */
682         ldq     $17,(17*8+offes_intregs)(a0)
683         ldq     $18,(18*8+offes_intregs)(a0)
684         ldq     $19,(19*8+offes_intregs)(a0)
685         ldq     $20,(20*8+offes_intregs)(a0)
686         ldq     $21,(21*8+offes_intregs)(a0)
687         ldq     $22,(22*8+offes_intregs)(a0)
688         ldq     $23,(23*8+offes_intregs)(a0)
689         ldq     $24,(24*8+offes_intregs)(a0)
690         ldq     $25,(25*8+offes_intregs)(a0)
691         ldq     $26,(26*8+offes_intregs)(a0)
692         /* $27 is pv                      */
693         ldq     $28,(28*8+offes_intregs)(a0)
694         ldq     $29,(29*8+offes_intregs)(a0)
695         /* $30 is sp                      */
696         /* $31 is zero                    */
697         
698         ldt     $f0 ,( 0*8+offes_fltregs)(a0)
699         ldt     $f1 ,( 1*8+offes_fltregs)(a0)
700         ldt     $f2 ,( 2*8+offes_fltregs)(a0)
701         ldt     $f3 ,( 3*8+offes_fltregs)(a0)
702         ldt     $f4 ,( 4*8+offes_fltregs)(a0)
703         ldt     $f5 ,( 5*8+offes_fltregs)(a0)
704         ldt     $f6 ,( 6*8+offes_fltregs)(a0)
705         ldt     $f7 ,( 7*8+offes_fltregs)(a0)
706         ldt     $f8 ,( 8*8+offes_fltregs)(a0)
707         ldt     $f9 ,( 9*8+offes_fltregs)(a0)
708         ldt     $f10,(10*8+offes_fltregs)(a0)
709         ldt     $f11,(11*8+offes_fltregs)(a0)
710         ldt     $f12,(12*8+offes_fltregs)(a0)
711         ldt     $f13,(13*8+offes_fltregs)(a0)
712         ldt     $f14,(14*8+offes_fltregs)(a0)
713         ldt     $f15,(15*8+offes_fltregs)(a0)
714         ldt     $f16,(16*8+offes_fltregs)(a0)
715         ldt     $f17,(17*8+offes_fltregs)(a0)
716         ldt     $f18,(18*8+offes_fltregs)(a0)
717         ldt     $f19,(19*8+offes_fltregs)(a0)
718         ldt     $f20,(20*8+offes_fltregs)(a0)
719         ldt     $f21,(21*8+offes_fltregs)(a0)
720         ldt     $f22,(22*8+offes_fltregs)(a0)
721         ldt     $f23,(23*8+offes_fltregs)(a0)
722         ldt     $f24,(24*8+offes_fltregs)(a0)
723         ldt     $f25,(25*8+offes_fltregs)(a0)
724         ldt     $f26,(26*8+offes_fltregs)(a0)
725         ldt     $f27,(27*8+offes_fltregs)(a0)
726         ldt     $f28,(28*8+offes_fltregs)(a0)
727         ldt     $f29,(29*8+offes_fltregs)(a0)
728         ldt     $f30,(30*8+offes_fltregs)(a0)
729         ldt     $f31,(31*8+offes_fltregs)(a0)
730
731         /* load new pc */
732
733         ldq     itmp3,offes_pc(a0)
734
735         /* load a0 */
736         
737         ldq     a0,(16*8+offes_intregs)(a0)
738         
739         /* jump to new code */
740
741         jmp     zero,(itmp3)
742
743         .end asm_replacement_in
744
745 /******************* function asm_initialize_thread_stack **********************
746 *                                                                              *
747 *   initialized a thread stack                                                 *
748 *                                                                              *
749 *******************************************************************************/
750
751         .ent    asm_initialize_thread_stack
752
753 asm_initialize_thread_stack:
754         lda     a1,-128(a1)
755         stq     zero, 0(a1)
756         stq     zero, 8(a1)
757         stq     zero, 16(a1)
758         stq     zero, 24(a1)
759         stq     zero, 32(a1)
760         stq     zero, 40(a1)
761         stq     zero, 48(a1)
762         stt     fzero, 56(a1)
763         stt     fzero, 64(a1)
764         stt     fzero, 72(a1)
765         stt     fzero, 80(a1)
766         stt     fzero, 88(a1)
767         stt     fzero, 96(a1)
768         stt     fzero, 104(a1)
769         stt     fzero, 112(a1)
770         stq     a0, 120(a1)
771         mov     a1, v0
772         jmp     zero,(ra)
773
774         .end    asm_initialize_thread_stack
775
776
777 /******************* function asm_perform_threadswitch *************************
778 *                                                                              *
779 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
780 *                                                                              *
781 *   performs a threadswitch                                                    *
782 *                                                                              *
783 *******************************************************************************/
784
785         .ent    asm_perform_threadswitch
786
787 asm_perform_threadswitch:
788         subq    sp,128,sp
789         stq     s0, 0(sp)
790         stq     s1, 8(sp)
791         stq     s2, 16(sp)
792         stq     s3, 24(sp)
793         stq     s4, 32(sp)
794         stq     s5, 40(sp)
795         stq     s6, 48(sp)
796         stt     fs0, 56(sp)
797         stt     fs1, 64(sp)
798         stt     fs2, 72(sp)
799         stt     fs3, 80(sp)
800         stt     fs4, 88(sp)
801         stt     fs5, 96(sp)
802         stt     fs6, 104(sp)
803         stt     fs7, 112(sp)
804         stq     ra, 120(sp)
805         stq     sp, 0(a0)
806         stq     sp, 0(a2)
807         ldq     sp, 0(a1)
808         ldq     s0, 0(sp)
809         ldq     s1, 8(sp)
810         ldq     s2, 16(sp)
811         ldq     s3, 24(sp)
812         ldq     s4, 32(sp)
813         ldq     s5, 40(sp)
814         ldq     s6, 48(sp)
815         ldt     fs0, 56(sp)
816         ldt     fs1, 64(sp)
817         ldt     fs2, 72(sp)
818         ldt     fs3, 80(sp)
819         ldt     fs4, 88(sp)
820         ldt     fs5, 96(sp)
821         ldt     fs6, 104(sp)
822         ldt     fs7, 112(sp)
823         ldq     ra, 120(sp)
824         mov     ra, pv
825         addq    sp, 128, sp
826         jmp     zero,(ra)
827
828         .end    asm_perform_threadswitch
829
830
831 /********************* function asm_switchstackandcall *************************
832 *                                                                              *
833 *  void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
834 *                               void *p);                                      *
835 *                                                                              *
836 *   Switches to a new stack, calls a function and switches back.               *
837 *       a0      new stack pointer                                              *
838 *       a1      function pointer                                               *
839 *               a2              pointer to variable where stack top should be stored           *
840 *               a3      pointer to user data, is passed to the function                *
841 *                                                                              *
842 *******************************************************************************/
843
844
845         .ent    asm_switchstackandcall
846
847 asm_switchstackandcall:
848         lda     a0,-2*8(a0)     /* allocate new stack                                 */
849         stq     ra,0(a0)        /* save return address on new stack                   */
850         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
851         stq sp,0(a2)        /* save old stack pointer to variable                 */
852         mov     a0,sp           /* switch to new stack                                */
853         
854         mov     a1,pv           /* load function pointer                              */
855         mov a3,a0           /* pass pointer */
856         jmp     ra,(pv)         /* and call function                                  */
857
858         ldq     ra,0(sp)        /* load return address                                */
859         ldq     sp,1*8(sp)      /* switch to old stack                                */
860
861         jmp     zero,(ra)       /* return                                             */
862
863         .end    asm_switchstackandcall
864
865
866         .ent    asm_getclassvalues_atomic
867
868 asm_getclassvalues_atomic:
869 _crit_restart:
870 _crit_begin:
871         ldl     t0,offbaseval(a0)
872         ldl     t1,offdiffval(a0)
873         ldl     t2,offbaseval(a1)
874 _crit_end:
875         stl     t0,offcast_super_baseval(a2)
876         stl     t1,offcast_super_diffval(a2)
877         stl     t2,offcast_sub_baseval(a2)
878         jmp     zero,(ra)
879
880         .end    asm_getclassvalues_atomic
881
882
883     .data
884
885 asm_criticalsections:
886 #if defined(ENABLE_THREADS)
887     .quad   _crit_begin
888     .quad   _crit_end
889     .quad   _crit_restart
890 #endif
891     .quad   0
892
893
894 /* asm_md_init *****************************************************************
895
896    Initialize machine dependent stuff.
897
898    Determines if the byte support instruction set (21164a and higher)
899    is available.
900
901 *******************************************************************************/
902
903         .ent    asm_md_init
904
905 asm_md_init:
906         .long   0x47e03c20                  /* amask   1,v0                       */
907         jmp     zero,(ra)                   /* return                             */
908
909         .end    asm_md_init
910
911
912 /* asm_cacheflush **************************************************************
913
914    XXX
915
916 *******************************************************************************/
917
918         .ent    asm_cacheflush
919
920 asm_cacheflush:
921         call_pal PAL_imb              /* synchronize instruction cache            */
922         jmp     zero,(ra)
923
924         .end    asm_cacheflush
925
926
927 /* Disable exec-stacks, required for Gentoo ***********************************/
928
929 #if defined(__GCC__) && defined(__ELF__)
930         .section .note.GNU-stack,"",@progbits
931 #endif
932
933
934 /*
935  * These are local overrides for various environment variables in Emacs.
936  * Please do not remove this and leave it at the end of the file, where
937  * Emacs will automagically detect them.
938  * ---------------------------------------------------------------------
939  * Local variables:
940  * mode: asm
941  * indent-tabs-mode: t
942  * c-basic-offset: 4
943  * tab-width: 4
944  * End:
945  * vim:noexpandtab:sw=4:ts=4:
946  */