142e758a386e2683d11a461b88f82c1394fc29ac
[cacao.git] / src / vm / jit / alpha / asmpart.S
1 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: asmpart.S 8186 2007-07-05 23:48:16Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include "vm/jit/alpha/md-abi.h"
33 #include "vm/jit/alpha/md-asm.h"
34 #include "vm/jit/alpha/offsets.h"
35
36 #include "vm/jit/abi-asm.h"
37 #include "vm/jit/methodheader.h"
38
39
40         .text
41         .set    noat
42         .set    noreorder
43
44
45 /* export functions ***********************************************************/
46
47         .globl asm_vm_call_method
48         .globl asm_vm_call_method_int
49         .globl asm_vm_call_method_long
50         .globl asm_vm_call_method_float
51         .globl asm_vm_call_method_double
52         .globl asm_vm_call_method_exception_handler
53         .globl asm_vm_call_method_end
54
55         .globl asm_call_jit_compiler
56
57         .globl asm_handle_exception
58         .globl asm_handle_nat_exception
59
60         .globl asm_abstractmethoderror
61
62 #if defined(ENABLE_REPLACEMENT)
63         .globl asm_replacement_out
64         .globl asm_replacement_in
65 #endif
66
67         .globl asm_compare_and_swap
68         .globl asm_memory_barrier
69
70         .globl asm_criticalsections
71         .globl asm_getclassvalues_atomic
72
73         .globl asm_md_init
74         .globl asm_cacheflush
75
76
77 /* asm_vm_call_method **********************************************************
78 *                                                                              *
79 *   This function calls a Java-method (which possibly needs compilation)       *
80 *   with up to 4 address parameters.                                           *
81 *                                                                              *
82 *   This functions calls the JIT-compiler which eventually translates the      *
83 *   method into machine code.                                                  *
84 *                                                                              *
85 *   C-prototype:                                                               *
86 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
87 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
88 *                                                                              *
89 *******************************************************************************/
90
91         .ent    asm_vm_call_method
92
93         .align  3
94
95         .quad   0                           /* catch type all                     */
96         .quad   0                           /* handler pc                         */
97         .quad   0                           /* end pc                             */
98         .quad   0                           /* start pc                           */
99         .long   1                           /* extable size                       */
100         .long   0                           /* ALIGNMENT PADDING                  */
101         .quad   0                           /* line number table start            */
102         .quad   0                           /* line number table size             */
103         .long   0                           /* ALIGNMENT PADDING                  */
104         .long   0                           /* fltsave                            */
105         .long   1                           /* intsave                            */
106         .long   0                           /* isleaf                             */
107         .long   0                           /* IsSync                             */
108         .long   0                           /* frame size                         */
109         .quad   0                           /* codeinfo pointer                   */
110
111 asm_vm_call_method:
112 asm_vm_call_method_int:
113 asm_vm_call_method_long:
114 asm_vm_call_method_float:
115 asm_vm_call_method_double:
116         ldgp    gp,0(pv)
117         lda     sp,-5*8(sp)               /* allocate stack space                 */
118         stq     ra,0*8(sp)                /* save return address                  */
119         stq     gp,1*8(sp)                /* save global pointer                  */
120         stq     s6,3*8(sp)
121
122         stq     a0,4*8(sp)                /* save method pointer for compiler     */
123
124         mov     a2,t0                     /* pointer to arg block                 */
125         mov     a1,s6                     /* arg count                            */
126
127         ble     s6,calljava_argsloaded
128         lda     s6,-1(s6)
129         ldq     a0,offvmargdata(t0)
130         ldt     $f16,offvmargdata(t0)
131         ble     s6,calljava_argsloaded
132
133         lda     s6,-1(s6)
134         ldq     a1,offvmargdata+sizevmarg*1(t0)
135         ldt     $f17,offvmargdata+sizevmarg*1(t0)
136         ble     s6,calljava_argsloaded
137
138         lda     s6,-1(s6)
139         ldq     a2,offvmargdata+sizevmarg*2(t0)
140         ldt     $f18,offvmargdata+sizevmarg*2(t0)
141         ble     s6,calljava_argsloaded
142
143         lda     s6,-1(s6)
144         ldq     a3,offvmargdata+sizevmarg*3(t0)
145         ldt     $f19,offvmargdata+sizevmarg*3(t0)
146         ble     s6,calljava_argsloaded
147
148         lda     s6,-1(s6)
149         ldq     a4,offvmargdata+sizevmarg*4(t0)
150         ldt     $f20,offvmargdata+sizevmarg*4(t0)
151         ble     s6,calljava_argsloaded
152
153         lda     s6,-1(s6)
154         ldq     a5,offvmargdata+sizevmarg*5(t0)
155         ldt     $f21,offvmargdata+sizevmarg*5(t0)
156 calljava_argsloaded:
157         mov     sp,t4
158         ble     s6,calljava_nocopy
159         negq    s6,t1
160         s8addq  t1,sp,sp
161         s8addq  t1,t4,t2
162
163 calljava_copyloop:
164         ldq     t3,offvmargdata+sizevmarg*6(t0)
165         stq     t3,0(t2)
166         lda     t1,1(t1)
167         lda     t0,sizevmarg(t0)
168         lda     t2,8(t2)
169         bne     t1,calljava_copyloop
170
171 calljava_nocopy:
172         ldq     itmp1,4*8(t4)             /* pass method pointer via itmp1        */
173
174         lda     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
175         stq     mptr,2*8(t4)              /* store function address               */
176         lda     mptr,1*8(t4)              /* set method pointer                   */
177
178         ldq     pv,1*8(mptr)              /* method call as in Java               */
179         jmp     ra,(pv)                   /* call JIT compiler                    */
180 calljava_jit2:
181         lda     pv,(asm_vm_call_method - calljava_jit2)(ra)
182
183         s8addq  s6,sp,sp
184 calljava_return2:
185         ldq     ra,0*8(sp)                /* restore return address               */
186         ldq     gp,1*8(sp)                /* restore global pointer               */
187         ldq     s6,3*8(sp)
188         lda     sp,5*8(sp)                /* free stack space                     */
189
190 calljava_ret2:
191         jmp     zero,(ra)
192
193 asm_vm_call_method_exception_handler:
194         s8addq  s6,sp,sp
195         ldq     gp,1*8(sp)                /* restore global pointer               */
196         mov     itmp1,a0
197         jsr     ra,builtin_throw_exception
198         ldq     ra,0*8(sp)                /* restore return address               */
199         ldq     s6,3*8(sp)
200         lda     sp,5*8(sp)                /* free stack space                     */
201 asm_vm_call_method_end:                                 
202         jmp     zero,(ra)
203
204         .end    asm_vm_call_method
205
206
207 /* asm_call_jit_compiler *******************************************************
208
209    Invokes the compiler for untranslated Java methods.
210
211 *******************************************************************************/
212
213         .ent    asm_call_jit_compiler
214
215 asm_call_jit_compiler:
216         ldgp    gp,0(pv)
217         lda     sp,-(ARG_CNT+2)*8(sp) /* +2: keep stack 16-byte aligned           */
218
219         stq     ra,0*8(sp)            /* save return address                      */
220
221         SAVE_ARGUMENT_REGISTERS(1)    /* save 6 int/6 float argument registers    */
222
223         mov     itmp1,a0              /* pass methodinfo pointer                  */
224         mov     mptr,a1               /* pass method pointer                      */
225         lda     a2,(ARG_CNT+2)*8(sp)  /* pass java sp                             */
226         mov     ra,a3
227         jsr     ra,jit_asm_compile    /* call jit compiler                        */
228         mov     v0,pv
229
230         ldq     ra,0*8(sp)            /* load return address                      */
231
232         RESTORE_ARGUMENT_REGISTERS(1) /* restore 6 int/6 float argument registers */
233
234         lda     sp,(ARG_CNT+2)*8(sp)  /* remove stack frame                       */
235
236         beq     pv,L_asm_call_jit_compiler_exception
237
238         jmp     zero,(pv)             /* and call method, the method returns      */
239                                       /* directly to the caller (ra).             */
240
241 L_asm_call_jit_compiler_exception:
242         subq    sp,2*8,sp
243         stq     ra,0*8(sp)            /* save return address (xpc)                */
244         jsr     ra,exceptions_get_and_clear_exception
245         ldq     ra,0*8(sp)            /* restore return address (xpc)             */
246         addq    sp,2*8,sp
247
248         mov     v0,xptr               /* get exception                            */
249         subq    ra,4,xpc              /* exception address is ra - 4              */
250         br      L_asm_handle_nat_exception
251
252         .end    asm_call_jit_compiler
253
254
255 /* asm_handle_exception ********************************************************
256
257    This function handles an exception. It does not use the usual calling
258    conventions. The exception pointer is passed in REG_ITMP1 and the
259    pc from the exception raising position is passed in REG_ITMP2. It searches
260    the local exception table for a handler. If no one is found, it unwinds
261    stacks and continues searching the callers.
262
263    ATTENTION: itmp3 == gp!
264
265 *******************************************************************************/
266
267         .ent    asm_handle_nat_exception
268
269 asm_handle_nat_exception:
270 L_asm_handle_nat_exception:       /* required for PIC code                    */
271 L_asm_handle_exception_stack_loop:
272         lda     sp,-6*8(sp)                 /* keep stack 16-byte aligned         */
273         stq     xptr,0*8(sp)                /* save xptr                          */
274         stq     xpc,1*8(sp)                 /* save xpc                           */
275         stq     ra,3*8(sp)                  /* save RA                            */
276         stq     zero,4*8(sp)                /* save maybe-leaf flag (cleared)     */
277
278         mov     ra,a0                       /* pass RA                            */
279
280         br      ra,L_asm_handle_exception_load_gp
281 L_asm_handle_exception_load_gp:
282         ldgp    gp,0(ra)                    /* load gp                            */
283
284         jsr     ra,md_codegen_get_pv_from_pc/* get PV from RA                     */
285         stq     v0,2*8(sp)                  /* save PV                            */
286
287         ldq     a0,0*8(sp)                  /* pass xptr                          */
288         ldq     a1,1*8(sp)                  /* pass xpc                           */
289         mov     v0,a2                       /* pass PV                            */
290         addq    sp,6*8,a3                   /* pass Java SP                       */
291
292         br      L_asm_handle_exception_continue
293
294         .aent    asm_handle_exception
295
296 asm_handle_exception:
297 L_asm_handle_exception:                 /* required for PIC code              */
298         lda     sp,-(ARG_CNT+TMP_CNT)*8(sp) /* create maybe-leaf stackframe       */
299
300         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
301         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
302
303         lda     sp,-6*8(sp)                 /* keep stack 16-byte aligned         */
304         stq     xptr,0*8(sp)                /* save xptr                          */
305         stq     pv,2*8(sp)                  /* save PV                            */
306         stq     ra,3*8(sp)                  /* save RA                            */
307         lda     t0,1(zero)                  /* set maybe-leaf flag                */
308         stq     t0,4*8(sp)                  /* save maybe-leaf flag               */
309
310         br      ra,L_asm_handle_exception_load_gp_2
311 L_asm_handle_exception_load_gp_2:
312         ldgp    gp,0(ra)                    /* load gp                            */
313
314         mov     xptr,a0                     /* pass xptr                          */
315         mov     xpc,a1                      /* pass xpc                           */
316         mov     pv,a2                       /* pass PV                            */
317         lda     a3,(ARG_CNT+TMP_CNT+6)*8(sp)/* pass Java SP                       */
318
319 L_asm_handle_exception_continue:
320         jsr     ra,exceptions_handle_exception
321
322         beq     v0,L_asm_handle_exception_not_catched
323
324         mov     v0,xpc                      /* move handlerpc into xpc            */
325         ldq     xptr,0*8(sp)                /* restore xptr                       */
326         ldq     pv,2*8(sp)                  /* restore PV                         */
327         ldq     ra,3*8(sp)                  /* restore RA                         */
328         ldq     t0,4*8(sp)                  /* get maybe-leaf flag                */
329         lda     sp,6*8(sp)                  /* free stack frame                   */
330
331         beq     t0,L_asm_handle_exception_no_leaf
332
333         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
334         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
335         
336         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
337
338 L_asm_handle_exception_no_leaf:
339         jmp     zero,(xpc)                  /* jump to the handler                */
340
341 L_asm_handle_exception_not_catched:
342         ldq     xptr,0*8(sp)                /* restore xptr                       */
343         ldq     pv,2*8(sp)                  /* restore PV                         */
344         ldq     ra,3*8(sp)                  /* restore RA                         */
345         ldq     t0,4*8(sp)                  /* get maybe-leaf flag                */
346         lda     sp,6*8(sp)
347
348         beq     t0,L_asm_handle_exception_no_leaf_stack
349
350         lda     sp,(ARG_CNT+TMP_CNT)*8(sp)  /* remove maybe-leaf stackframe       */
351         mov     zero,t0                     /* clear the maybe-leaf flag          */
352
353 L_asm_handle_exception_no_leaf_stack:
354         ldl     t1,FrameSize(pv)            /* get frame size                     */
355         addq    t1,sp,t1                    /* pointer to save area               */
356
357         ldl     t2,IsLeaf(pv)               /* is leaf procedure                  */
358         bne     t2,L_asm_handle_exception_no_ra_restore
359
360         ldq     ra,-1*8(t1)                 /* restore ra                         */
361         subq    t1,8,t1                     /* t1--                               */
362
363 L_asm_handle_exception_no_ra_restore:
364         mov     ra,xpc                      /* the new xpc is ra                  */
365         ldl     t2,IntSave(pv)              /* t2 = saved int register count      */
366         br      t3,ex_int1                  /* t3 = current pc                    */
367 ex_int1:
368         lda     t3,(ex_int2 - ex_int1)(t3)
369         negl    t2,t2                       /* negate register count              */
370         s4addq  t2,t3,t3                    /* t2 = IntSave - register count * 4  */
371         jmp     zero,(t3)                   /* jump to save position              */
372
373         ldq     s0,-7*8(t1)
374         ldq     s1,-6*8(t1)
375         ldq     s2,-5*8(t1)
376         ldq     s3,-4*8(t1)
377         ldq     s4,-3*8(t1)
378         ldq     s5,-2*8(t1)
379         ldq     s6,-1*8(t1)
380
381 ex_int2:
382         s8addq  t2,t1,t1                    /* t1 = t1 - 8 * register count       */
383
384         ldl     t2,FltSave(pv)              /* t2 = saved flt register count      */
385         br      t3,ex_flt1                  /* t3 = current pc                    */
386 ex_flt1:
387         lda     t3,(ex_flt2 - ex_flt1)(t3)
388         negl    t2,t2                       /* negate register count              */
389         s4addq  t2,t3,t3                    /* t2 = FltSave - 4 * register count  */
390         jmp     zero,(t3)                   /* jump to save position              */
391
392         ldt     fs0,-8*8(t1)
393         ldt     fs1,-7*8(t1)
394         ldt     fs2,-6*8(t1)
395         ldt     fs3,-5*8(t1)
396         ldt     fs4,-4*8(t1)
397         ldt     fs5,-3*8(t1)
398         ldt     fs6,-2*8(t1)
399         ldt     fs7,-1*8(t1)
400
401 ex_flt2:
402         ldl     t1,FrameSize(pv)            /* get frame size                     */
403         addq    sp,t1,sp                    /* unwind stack                       */
404         br      L_asm_handle_exception_stack_loop
405
406         .end    asm_handle_nat_exception
407
408
409 /* asm_abstractmethoderror *****************************************************
410
411    Creates and throws an AbstractMethodError.
412
413 *******************************************************************************/
414
415         .ent    asm_abstractmethoderror
416
417 asm_abstractmethoderror:
418         subq    sp,2*8,sp                   /* create stackframe                  */
419         stq     ra,0*8(sp)                  /* save return address                */
420         addq    sp,2*8,a0                   /* pass java sp                       */
421         mov     ra,a1                       /* pass exception address             */
422         jsr     ra,exceptions_asm_new_abstractmethoderror
423         ldq     ra,0*8(sp)                  /* restore return address             */
424         addq    sp,2*8,sp                   /* remove stackframe                  */
425
426         mov     v0,xptr                     /* get exception pointer              */
427         subq    ra,4,xpc                    /* exception address is ra - 4        */
428         br      L_asm_handle_nat_exception
429
430         .end    asm_abstractmethoderror
431
432
433 #if defined(ENABLE_REPLACEMENT)
434
435 /* asm_replacement_out *********************************************************
436
437    This code is jumped to from the replacement-out stubs that are executed
438    when a thread reaches an activated replacement point.
439
440    The purpose of asm_replacement_out is to read out the parts of the
441    execution state that cannot be accessed from C code, store this state,
442    and then call the C function replace_me.
443
444    Stack layout:
445      16                 start of stack inside method to replace
446       0   rplpoint *    info on the replacement point that was reached
447
448    NOTE: itmp3 has been clobbered by the replacement-out stub!
449
450 *******************************************************************************/
451
452 /* some room to accomodate changes of the stack frame size during replacement */
453         /* XXX we should find a cleaner solution here */
454 #define REPLACEMENT_ROOM  512
455
456 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
457
458         .ent asm_replacement_out
459
460 asm_replacement_out:
461     /* create stack frame */
462         lda     sp,-(REPLACEMENT_STACK_OFFSET)(sp)
463
464         /* save registers in execution state */
465         stq     $0 ,( 0*8+offes_intregs)(sp)
466         stq     $1 ,( 1*8+offes_intregs)(sp)
467         stq     $2 ,( 2*8+offes_intregs)(sp)
468         stq     $3 ,( 3*8+offes_intregs)(sp)
469         stq     $4 ,( 4*8+offes_intregs)(sp)
470         stq     $5 ,( 5*8+offes_intregs)(sp)
471         stq     $6 ,( 6*8+offes_intregs)(sp)
472         stq     $7 ,( 7*8+offes_intregs)(sp)
473         stq     $8 ,( 8*8+offes_intregs)(sp)
474         stq     $9 ,( 9*8+offes_intregs)(sp)
475         stq     $10,(10*8+offes_intregs)(sp)
476         stq     $11,(11*8+offes_intregs)(sp)
477         stq     $12,(12*8+offes_intregs)(sp)
478         stq     $13,(13*8+offes_intregs)(sp)
479         stq     $14,(14*8+offes_intregs)(sp)
480         stq     $15,(15*8+offes_intregs)(sp)
481         stq     $16,(16*8+offes_intregs)(sp)
482         stq     $17,(17*8+offes_intregs)(sp)
483         stq     $18,(18*8+offes_intregs)(sp)
484         stq     $19,(19*8+offes_intregs)(sp)
485         stq     $20,(20*8+offes_intregs)(sp)
486         stq     $21,(21*8+offes_intregs)(sp)
487         stq     $22,(22*8+offes_intregs)(sp)
488         stq     $23,(23*8+offes_intregs)(sp)
489         stq     $24,(24*8+offes_intregs)(sp)
490         stq     $25,(25*8+offes_intregs)(sp)
491         stq     $26,(26*8+offes_intregs)(sp)
492         stq     $27,(27*8+offes_intregs)(sp)
493         stq     $28,(28*8+offes_intregs)(sp)
494         stq     $29,(29*8+offes_intregs)(sp)
495         stq     $30,(30*8+offes_intregs)(sp)
496         stq     $31,(31*8+offes_intregs)(sp)
497         
498         stt     $f0 ,( 0*8+offes_fltregs)(sp)
499         stt     $f1 ,( 1*8+offes_fltregs)(sp)
500         stt     $f2 ,( 2*8+offes_fltregs)(sp)
501         stt     $f3 ,( 3*8+offes_fltregs)(sp)
502         stt     $f4 ,( 4*8+offes_fltregs)(sp)
503         stt     $f5 ,( 5*8+offes_fltregs)(sp)
504         stt     $f6 ,( 6*8+offes_fltregs)(sp)
505         stt     $f7 ,( 7*8+offes_fltregs)(sp)
506         stt     $f8 ,( 8*8+offes_fltregs)(sp)
507         stt     $f9 ,( 9*8+offes_fltregs)(sp)
508         stt     $f10,(10*8+offes_fltregs)(sp)
509         stt     $f11,(11*8+offes_fltregs)(sp)
510         stt     $f12,(12*8+offes_fltregs)(sp)
511         stt     $f13,(13*8+offes_fltregs)(sp)
512         stt     $f14,(14*8+offes_fltregs)(sp)
513         stt     $f15,(15*8+offes_fltregs)(sp)
514         stt     $f16,(16*8+offes_fltregs)(sp)
515         stt     $f17,(17*8+offes_fltregs)(sp)
516         stt     $f18,(18*8+offes_fltregs)(sp)
517         stt     $f19,(19*8+offes_fltregs)(sp)
518         stt     $f20,(20*8+offes_fltregs)(sp)
519         stt     $f21,(21*8+offes_fltregs)(sp)
520         stt     $f22,(22*8+offes_fltregs)(sp)
521         stt     $f23,(23*8+offes_fltregs)(sp)
522         stt     $f24,(24*8+offes_fltregs)(sp)
523         stt     $f25,(25*8+offes_fltregs)(sp)
524         stt     $f26,(26*8+offes_fltregs)(sp)
525         stt     $f27,(27*8+offes_fltregs)(sp)
526         stt     $f28,(28*8+offes_fltregs)(sp)
527         stt     $f29,(29*8+offes_fltregs)(sp)
528         stt     $f30,(30*8+offes_fltregs)(sp)
529         stt     $f31,(31*8+offes_fltregs)(sp)
530         
531         /* calculate sp of method */
532         lda     itmp1,(REPLACEMENT_STACK_OFFSET + 2*8)(sp)
533         stq     itmp1,(offes_sp)(sp)
534
535         br      ra,L_asm_replacement_out_load_gp
536 L_asm_replacement_out_load_gp:
537         ldgp    gp,0(ra)                    /* load gp                            */
538
539         /* store pv */
540         stq     pv,(offes_pv)(sp)
541
542         /* call replace_me */
543         ldq     a0,-(2*8)(itmp1)            /* arg0: rplpoint *                   */
544     mov     sp,a1                       /* arg1: execution state              */
545     jmp     zero,replace_me             /* call C function replace_me         */
546     jmp     zero,abort                  /* NEVER REACHED                      */
547
548         .end asm_replacement_out
549
550 /* asm_replacement_in **********************************************************
551
552    This code writes the given execution state and jumps to the replacement
553    code.
554
555    This function never returns!
556
557    NOTE: itmp3 is not restored!
558
559    C prototype:
560       void asm_replacement_in(executionstate *es, replace_safestack_t *st);
561
562 *******************************************************************************/
563
564         .ent asm_replacement_in
565         
566 asm_replacement_in:
567         /* a0 == executionstate *es */
568
569         /* get arguments */
570         mov     a1,s1                       /* replace_safestack_t *st            */
571         mov     a0,s2                       /* executionstate *es == safe stack   */
572
573         /* switch to the safe stack */
574         mov     s2,sp
575
576         /* call replace_build_execution_state(st) */
577         mov             s1,a0
578         jsr             ra,replace_build_execution_state
579
580         /* set new sp */
581         ldq             sp,(offes_sp)(s2)
582
583         /* build stack frame */
584         lda     sp,(-sizeexecutionstate)(sp)
585
586         /* call replace_free_safestack(st,& of allocated executionstate_t) */
587         mov             sp,a1 /* tmpes */
588         mov             s1,a0 /* st    */
589         jsr             ra,replace_free_safestack
590
591         /* set new pv */
592         ldq     pv,(offes_pv)(sp)
593         
594         /* copy registers from execution state */
595         ldq     $0 ,( 0*8+offes_intregs)(sp)
596         ldq     $1 ,( 1*8+offes_intregs)(sp)
597         ldq     $2 ,( 2*8+offes_intregs)(sp)
598         ldq     $3 ,( 3*8+offes_intregs)(sp)
599         ldq     $4 ,( 4*8+offes_intregs)(sp)
600         ldq     $5 ,( 5*8+offes_intregs)(sp)
601         ldq     $6 ,( 6*8+offes_intregs)(sp)
602         ldq     $7 ,( 7*8+offes_intregs)(sp)
603         ldq     $8 ,( 8*8+offes_intregs)(sp)
604         ldq     $9 ,( 9*8+offes_intregs)(sp)
605         ldq     $10,(10*8+offes_intregs)(sp)
606         ldq     $11,(11*8+offes_intregs)(sp)
607         ldq     $12,(12*8+offes_intregs)(sp)
608         ldq     $13,(13*8+offes_intregs)(sp)
609         ldq     $14,(14*8+offes_intregs)(sp)
610         ldq     $15,(15*8+offes_intregs)(sp)
611         ldq     a0, (16*8+offes_intregs)(sp)
612         ldq     $17,(17*8+offes_intregs)(sp)
613         ldq     $18,(18*8+offes_intregs)(sp)
614         ldq     $19,(19*8+offes_intregs)(sp)
615         ldq     $20,(20*8+offes_intregs)(sp)
616         ldq     $21,(21*8+offes_intregs)(sp)
617         ldq     $22,(22*8+offes_intregs)(sp)
618         ldq     $23,(23*8+offes_intregs)(sp)
619         ldq     $24,(24*8+offes_intregs)(sp)
620         ldq     $25,(25*8+offes_intregs)(sp)
621         ldq     $26,(26*8+offes_intregs)(sp)
622         /* $27 is pv                    */
623         ldq     $28,(28*8+offes_intregs)(sp)
624         ldq     $29,(29*8+offes_intregs)(sp)
625         /* $30 is sp                      */
626         /* $31 is zero                    */
627         
628         ldt     $f0 ,( 0*8+offes_fltregs)(sp)
629         ldt     $f1 ,( 1*8+offes_fltregs)(sp)
630         ldt     $f2 ,( 2*8+offes_fltregs)(sp)
631         ldt     $f3 ,( 3*8+offes_fltregs)(sp)
632         ldt     $f4 ,( 4*8+offes_fltregs)(sp)
633         ldt     $f5 ,( 5*8+offes_fltregs)(sp)
634         ldt     $f6 ,( 6*8+offes_fltregs)(sp)
635         ldt     $f7 ,( 7*8+offes_fltregs)(sp)
636         ldt     $f8 ,( 8*8+offes_fltregs)(sp)
637         ldt     $f9 ,( 9*8+offes_fltregs)(sp)
638         ldt     $f10,(10*8+offes_fltregs)(sp)
639         ldt     $f11,(11*8+offes_fltregs)(sp)
640         ldt     $f12,(12*8+offes_fltregs)(sp)
641         ldt     $f13,(13*8+offes_fltregs)(sp)
642         ldt     $f14,(14*8+offes_fltregs)(sp)
643         ldt     $f15,(15*8+offes_fltregs)(sp)
644         ldt     $f16,(16*8+offes_fltregs)(sp)
645         ldt     $f17,(17*8+offes_fltregs)(sp)
646         ldt     $f18,(18*8+offes_fltregs)(sp)
647         ldt     $f19,(19*8+offes_fltregs)(sp)
648         ldt     $f20,(20*8+offes_fltregs)(sp)
649         ldt     $f21,(21*8+offes_fltregs)(sp)
650         ldt     $f22,(22*8+offes_fltregs)(sp)
651         ldt     $f23,(23*8+offes_fltregs)(sp)
652         ldt     $f24,(24*8+offes_fltregs)(sp)
653         ldt     $f25,(25*8+offes_fltregs)(sp)
654         ldt     $f26,(26*8+offes_fltregs)(sp)
655         ldt     $f27,(27*8+offes_fltregs)(sp)
656         ldt     $f28,(28*8+offes_fltregs)(sp)
657         ldt     $f29,(29*8+offes_fltregs)(sp)
658         ldt     $f30,(30*8+offes_fltregs)(sp)
659         ldt     $f31,(31*8+offes_fltregs)(sp)
660
661         /* load new pc */
662
663         ldq     itmp3,offes_pc(sp)
664
665         /* remove stack frame */
666
667         lda             sp,(sizeexecutionstate)(sp)
668
669         /* jump to new code */
670
671         jmp     zero,(itmp3)
672
673         .end asm_replacement_in
674
675 #endif /* defined(ENABLE_REPLACEMENT) */
676
677
678 /* asm_compare_and_swap ********************************************************
679
680    Does an atomic compare and swap.  Required for the lock
681    implementation.
682
683    Atomically do the following: Check if the location still contains
684    `oldval`. If so, replace it by `newval` and return `oldval`.
685
686    RETURN VALUE:
687        the old value at *p
688
689    long compare_and_swap(volatile long *p, long oldval, long newval);
690
691 *******************************************************************************/
692
693         .ent    asm_compare_and_swap
694
695 asm_compare_and_swap:
696 1:
697         ldq_l   v0,0(a0)
698         cmpeq   v0,a1,t0
699         beq     t0,2f
700         mov     a2,t0
701         stq_c   t0,0(a0)
702         beq     t0,1b
703 2:
704         jmp     zero,(ra)
705
706         .end    asm_compare_and_swap
707
708
709 /* asm_memory_barrier **********************************************************
710
711    A memory barrier for the Java Memory Model.
712
713 *******************************************************************************/
714
715         .ent    asm_memory_barrier
716
717 asm_memory_barrier:
718         mb
719         jmp     zero,(ra)
720
721         .end    asm_memory_barrier
722
723
724         .ent    asm_getclassvalues_atomic
725
726 asm_getclassvalues_atomic:
727 _crit_restart:
728 _crit_begin:
729         ldl     t0,offbaseval(a0)
730         ldl     t1,offdiffval(a0)
731         ldl     t2,offbaseval(a1)
732 _crit_end:
733         stl     t0,offcast_super_baseval(a2)
734         stl     t1,offcast_super_diffval(a2)
735         stl     t2,offcast_sub_baseval(a2)
736         jmp     zero,(ra)
737
738         .end    asm_getclassvalues_atomic
739
740
741     .data
742
743 asm_criticalsections:
744 #if defined(ENABLE_THREADS)
745     .quad   _crit_begin
746     .quad   _crit_end
747     .quad   _crit_restart
748 #endif
749     .quad   0
750
751
752 /* asm_md_init *****************************************************************
753
754    Initialize machine dependent stuff.
755
756    Determines if the byte support instruction set (21164a and higher)
757    is available.
758
759 *******************************************************************************/
760
761         .ent    asm_md_init
762
763 asm_md_init:
764         .long   0x47e03c20                  /* amask   1,v0                       */
765         jmp     zero,(ra)                   /* return                             */
766
767         .end    asm_md_init
768
769
770 /* asm_cacheflush **************************************************************
771
772    XXX
773
774 *******************************************************************************/
775
776         .ent    asm_cacheflush
777
778 asm_cacheflush:
779         call_pal PAL_imb              /* synchronize instruction cache            */
780         jmp     zero,(ra)
781
782         .end    asm_cacheflush
783
784
785 /* disable exec-stacks ********************************************************/
786
787 #if defined(__linux__) && defined(__ELF__)
788         .section .note.GNU-stack,"",%progbits
789 #endif
790
791
792 /*
793  * These are local overrides for various environment variables in Emacs.
794  * Please do not remove this and leave it at the end of the file, where
795  * Emacs will automagically detect them.
796  * ---------------------------------------------------------------------
797  * Local variables:
798  * mode: asm
799  * indent-tabs-mode: t
800  * c-basic-offset: 4
801  * tab-width: 4
802  * End:
803  * vim:noexpandtab:sw=4:ts=4:
804  */