1 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
33 $Id: asmpart.S 2992 2005-07-11 21:52:07Z twisti $
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
41 #include "vm/jit/alpha/md-asm.h"
49 /********************* exported functions and variables ***********************/
51 .globl asm_sync_instruction_cache
52 .globl has_no_x_instr_set
54 .globl asm_calljavafunction
55 .globl asm_calljavafunction_int
57 .globl asm_calljavafunction2
58 .globl asm_calljavafunction2int
59 .globl asm_calljavafunction2long
60 .globl asm_calljavafunction2float
61 .globl asm_calljavafunction2double
63 .globl asm_call_jit_compiler
64 .globl asm_handle_exception
65 .globl asm_handle_nat_exception
67 .globl asm_wrapper_patcher
69 .globl asm_perform_threadswitch
70 .globl asm_initialize_thread_stack
71 .globl asm_switchstackandcall
72 .globl asm_criticalsections
73 .globl asm_getclassvalues_atomic
76 /* asm_sync_instruction_cache **************************************************
80 *******************************************************************************/
82 .ent asm_sync_instruction_cache
84 asm_sync_instruction_cache:
85 call_pal PAL_imb /* synchronize instruction cache */
88 .end asm_sync_instruction_cache
90 /*********************** function has_no_x_instr_set ***************************
92 * determines if the byte support instruction set (21164a and higher) *
95 *******************************************************************************/
97 .ent has_no_x_instr_set
100 .long 0x47e03c20 /* amask 1,v0 */
101 jmp zero,(ra) /* return */
103 .end has_no_x_instr_set
106 /********************* function asm_calljavafunction ***************************
108 * This function calls a Java-method (which possibly needs compilation) *
109 * with up to 4 address parameters. *
111 * This functions calls the JIT-compiler which eventually translates the *
112 * method into machine code. *
115 * javaobject_header *asm_calljavafunction (methodinfo *m, *
116 * void *arg1, void *arg2, void *arg3, void *arg4); *
118 *******************************************************************************/
120 .ent asm_calljavafunction
123 .ascii "calljavafunction\0\0"
126 .quad 0 /* catch type all */
127 .quad calljava_xhandler /* handler pc */
128 .quad calljava_xhandler /* end pc */
129 .quad asm_calljavafunction /* start pc */
130 .long 1 /* extable size */
131 .long 0 /* PADDING */
132 .quad 0 /* line number table start */
133 .quad 0 /* line number table size */
134 .long 0 /* PADDING */
135 .long 0 /* fltsave */
136 .long 0 /* intsave */
139 .long 32 /* frame size */
140 .quad 0 /* method pointer (pointer to name) */
142 asm_calljavafunction:
143 asm_calljavafunction_int:
145 lda sp,-32(sp) /* allocate stack space */
146 stq gp,24(sp) /* save global pointer */
147 stq ra,0(sp) /* save return address */
149 stq a0,16(sp) /* save method pointer for compiler */
150 lda v0,16(sp) /* pass pointer to method pointer via v0*/
152 mov a1,a0 /* pass the remaining parameters */
157 lda itmp2,asm_call_jit_compiler/* fake virtual function call (2 instr)*/
158 stq itmp2,8(sp) /* store function address */
159 mov sp,itmp2 /* set method pointer */
161 ldq pv,8(itmp2) /* method call as in Java */
162 jmp ra,(pv) /* call JIT compiler */
164 lda pv,(asm_calljavafunction - calljava_jit)(ra)
167 ldq ra,0(sp) /* restore return address */
168 ldq gp,24(sp) /* restore global pointer */
169 lda sp,32(sp) /* free stack space */
175 ldq gp,24(sp) /* restore global pointer */
177 jsr ra,builtin_throw_exception
178 ldq ra,0(sp) /* restore return address */
179 lda sp,32(sp) /* free stack space */
180 mov zero,v0 /* return NULL */
182 .end asm_calljavafunction
187 .ent asm_calljavafunction2
192 .quad 0 /* catch type all */
193 .quad calljava_xhandler2 /* handler pc */
194 .quad calljava_xhandler2 /* end pc */
195 .quad asm_calljavafunction2 /* start pc */
196 .long 1 /* extable size */
197 .long 0 /* PADDING */
198 .quad 0 /* line number table start */
199 .quad 0 /* line number table size */
200 .long 0 /* PADDING */
201 .long 0 /* fltsave */
202 .long 1 /* intsave */
205 .long 40 /* frame size */
206 .quad 0 /* method pointer (pointer to name) */
208 asm_calljavafunction2:
209 asm_calljavafunction2int:
210 asm_calljavafunction2long:
211 asm_calljavafunction2float:
212 asm_calljavafunction2double:
214 lda sp,-5*8(sp) /* allocate stack space */
215 stq ra,0*8(sp) /* save return address */
216 stq gp,1*8(sp) /* save global pointer */
219 stq a0,4*8(sp) /* save method pointer for compiler */
220 mov a3,t0 /* pointer to arg block */
221 mov a1,s6 /* arg count */
223 ble s6,calljava_argsloaded
225 ldq a0,offjniitem(t0)
226 ldt $f16,offjniitem(t0)
227 ble s6,calljava_argsloaded
230 ldq a1,offjniitem+sizejniblock*1(t0)
231 ldt $f17,offjniitem+sizejniblock*1(t0)
232 ble s6,calljava_argsloaded
235 ldq a2,offjniitem+sizejniblock*2(t0)
236 ldt $f18,offjniitem+sizejniblock*2(t0)
237 ble s6,calljava_argsloaded
240 ldq a3,offjniitem+sizejniblock*3(t0)
241 ldt $f19,offjniitem+sizejniblock*3(t0)
242 ble s6,calljava_argsloaded
245 ldq a4,offjniitem+sizejniblock*4(t0)
246 ldt $f20,offjniitem+sizejniblock*4(t0)
247 ble s6,calljava_argsloaded
250 ldq a5,offjniitem+sizejniblock*5(t0)
251 ldt $f21,offjniitem+sizejniblock*5(t0)
254 ble s6,calljava_nocopy
260 ldq t3,offjniitem+sizejniblock*6(t0)
263 lda t0,sizejniblock(t0)
265 bne t1,calljava_copyloop
268 lda v0,4*8(t4) /* pass pointer to method pointer via v0*/
270 lda itmp2,asm_call_jit_compiler/* fake virtual function call (2 instr)*/
271 stq itmp2,16(t4) /* store function address */
272 lda itmp2,8(t4) /* set method pointer */
274 ldq pv,8(itmp2) /* method call as in Java */
275 jmp ra,(pv) /* call JIT compiler */
277 lda pv,(asm_calljavafunction2 - calljava_jit2)(ra)
281 ldq ra,0*8(sp) /* restore return address */
282 ldq gp,1*8(sp) /* restore global pointer */
284 lda sp,5*8(sp) /* free stack space */
291 ldq gp,1*8(sp) /* restore global pointer */
293 jsr ra,builtin_throw_exception
294 ldq ra,0*8(sp) /* restore return address */
296 lda sp,5*8(sp) /* free stack space */
297 mov zero,v0 /* return NULL */
300 .end asm_calljavafunction2
303 /****************** function asm_call_jit_compiler *****************************
305 * invokes the compiler for untranslated JavaVM methods. *
307 * Register R0 contains a pointer to the method info structure (prepared *
308 * by createcompilerstub). Using the return address in R26 and the *
309 * offset in the LDA instruction or using the value in methodptr R28 the *
310 * patching address for storing the method address can be computed: *
312 * method address was either loaded using *
313 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
314 * M_LDA (REG_PV, REG_RA, low) *
315 * M_LDAH(REG_PV, REG_RA, high) ; optional *
317 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
318 * in the static case the method pointer can be computed using the *
319 * return address and the lda function following the jmp instruction *
321 *******************************************************************************/
323 .ent asm_call_jit_compiler
325 asm_call_jit_compiler:
327 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
328 srl t8,16,t8 /* shift right register number $yy */
329 and t8,31,t8 /* isolate register number */
330 subl t8,28,t8 /* test for REG_METHODPTR */
332 ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
334 sra t8,48,t8 /* isolate offset */
335 addq t8,ra,$28 /* compute update address */
336 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
337 srl t8,16,t8 /* isolate instruction code */
338 lda t8,-0x177b(t8) /* test for LDAH */
340 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
341 sll t8,16,t8 /* compute high offset */
342 addl t8,0,t8 /* sign extend high offset */
343 addq t8,$28,$28 /* compute update address */
345 lda sp,-14*8(sp) /* reserve stack space */
347 SAVE_ARGUMENT_REGISTERS(0) /* save 6 int/6 float argument registers */
349 stq $28,12*8(sp) /* save method pointer */
350 stq ra,13*8(sp) /* save return address */
352 ldq a0,0(v0) /* pass 'methodinfo' pointer to */
353 jsr ra,jit_compile /* jit compiler */
356 RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
358 ldq $28,12*8(sp) /* load method pointer */
359 ldq ra,13*8(sp) /* load return address */
360 lda sp,14*8(sp) /* deallocate stack area */
362 beq v0,L_asm_call_jit_compiler_exception
364 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
366 sra t8,48,t8 /* isolate offset */
368 addq t8,$28,t8 /* compute update address via method pointer*/
369 stq v0,0(t8) /* save new method address there */
371 call_pal PAL_imb /* synchronise instruction cache */
373 mov v0,pv /* load method address into pv */
374 jmp zero,(pv) /* and call method. The method returns */
375 /* directly to the caller (ra). */
377 L_asm_call_jit_compiler_exception:
381 mov zero,a0 /* fill in the correct stacktrace */
382 lda a1,1*8(sp) /* pass sp of parent Java function */
383 mov ra,a2 /* pass ra to parent Java function */
384 mov ra,a3 /* xpc is the same as ra */
385 jsr ra,stacktrace_extern_fillInStackTrace
392 br asm_handle_nat_exception
394 .end asm_call_jit_compiler
397 /********************* function asm_handle_exception ***************************
399 * This function handles an exception. It does not use the usual calling *
400 * conventions. The exception pointer is passed in REG_ITMP1 and the *
401 * pc from the exception raising position is passed in REG_ITMP2. It searches *
402 * the local exception table for a handler. If no one is found, it unwinds *
403 * stacks and continues searching the callers. *
405 * void asm_handle_exception (exceptionptr, exceptionpc); *
407 *******************************************************************************/
409 .ent asm_handle_nat_exception
411 asm_handle_nat_exception:
412 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
414 sra t0,48,t0 /* isolate offset */
415 addq t0,ra,pv /* compute update address */
416 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
417 srl t0,16,t0 /* isolate instruction code */
418 lda t0,-0x177b(t0) /* test for LDAH */
419 bne t0,asm_handle_exception
420 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
421 sll t0,16,t0 /* compute high offset */
422 addl t0,0,t0 /* sign extend high offset */
423 addq t0,pv,pv /* compute update address */
425 .aent asm_handle_exception
427 asm_handle_exception:
428 lda sp,-18*8(sp) /* allocate stack */
429 stq t0,0*8(sp) /* save possible used registers */
430 stq t1,1*8(sp) /* also registers used by trace_exception */
448 lda t3,1(zero) /* set no unwind flag */
450 lda sp,-5*8(sp) /* allocate stack */
451 stq xptr,0*8(sp) /* save used register */
458 ldq a1,MethodPointer(pv)
463 br ra,ex_trace /* set ra for gp loading */
465 ldgp gp,0(ra) /* load gp */
466 jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
468 ldq xptr,0*8(sp) /* restore used register */
473 lda sp,5*8(sp) /* deallocate stack */
475 ldl t0,ExTableSize(pv) /* t0 = exception table size */
476 beq t0,empty_table /* if empty table skip */
478 lda t1,ExTableStart(pv) /* t1 = start of exception table */
481 ldq t2,ExStartPC(t1) /* t2 = exception start pc */
482 cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
483 beq t2,ex_table_cont /* if (false) continue */
484 ldq t2,ExEndPC(t1) /* t2 = exception end pc */
485 cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
486 beq t2,ex_table_cont /* if (false) continue */
487 ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
488 beq a1,ex_handle_it /* NULL catches everything */
490 ldl itmp3,offclassloaded(a1)
491 bne itmp3,L_class_loaded
493 subq sp,8*8,sp /* allocate stack */
494 stq t0,0*8(sp) /* save used register */
505 br ra,L_class_load_ra /* set ra for gp loading */
507 ldgp gp,0(ra) /* load gp */
508 jsr ra,load_class_bootstrap
510 ldq t0,0*8(sp) /* restore used register */
518 addq sp,8*8,sp /* deallocate stack */
521 ldl itmp3,offclasslinked(a1)
522 subq sp,8*8,sp /* allocate stack */
524 bne itmp3,L_class_linked
526 stq t0,0*8(sp) /* save used register */
536 br ra,L_class_link_ra /* set ra for gp loading */
538 ldgp gp,0(ra) /* load gp */
541 ldq t0,0*8(sp) /* restore used register */
553 ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
554 ldq a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
555 ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
556 ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
557 ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
559 subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
560 cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
561 addq sp,8*8,sp /* deallocate stack */
562 beq v0,ex_table_cont /* if (false) continue */
565 ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
567 beq t3,ex_jump /* if (!(no stack unwinding) skip */
569 ldq t0,0*8(sp) /* restore possible used registers */
570 ldq t1,1*8(sp) /* also registers used by trace_exception */
587 lda sp,18*8(sp) /* deallocate stack */
590 jmp zero,(xpc) /* jump to the handler */
593 lda t1,ExEntrySize(t1) /* next exception table entry */
594 subl t0,1,t0 /* decrement entry counter */
595 bgt t0,ex_table_loop /* if (t0 > 0) next entry */
598 beq t3,ex_already_cleared /* if here the first time, then */
599 lda sp,18*8(sp) /* deallocate stack and */
600 clr t3 /* clear the no unwind flag */
602 ldl t0,IsSync(pv) /* t0 = SyncOffset */
603 beq t0,no_monitor_exit /* if zero no monitorexit */
605 #if defined(USE_THREADS)
606 addq sp,t0,t0 /* add stackptr to Offset */
607 ldq a0,-8(t0) /* load monitorexit pointer */
609 lda sp,-7*8(sp) /* allocate stack */
610 stq t0,0*8(sp) /* save used register */
618 br ra,ex_mon_load /* set ra for gp loading */
620 ldgp gp,0(ra) /* load gp */
621 jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
623 ldq t0,0*8(sp) /* restore used register */
630 lda sp,7*8(sp) /* deallocate stack */
634 ldl t0,FrameSize(pv) /* t0 = frame size */
635 addq sp,t0,sp /* unwind stack */
636 mov sp,t0 /* t0 = pointer to save area */
637 ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
638 bne t1,ex_no_restore /* if (leaf) skip */
639 ldq ra,-8(t0) /* restore ra */
640 lda t0,-8(t0) /* t0-- */
642 mov ra,xpc /* the new xpc is ra */
643 ldl t1,IntSave(pv) /* t1 = saved int register count */
644 br t2,ex_int1 /* t2 = current pc */
646 lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
647 negl t1,t1 /* negate register count */
648 s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
649 jmp zero,(t2) /* jump to save position */
658 s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
660 ldl t1,FltSave(pv) /* t1 = saved flt register count */
661 br t2,ex_flt1 /* t2 = current pc */
663 lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
664 negl t1,t1 /* negate register count */
665 s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
666 jmp zero,(t2) /* jump to save position */
676 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
678 sra t0,48,t0 /* isolate offset */
679 addq t0,ra,pv /* compute update address */
680 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
681 srl t0,16,t0 /* isolate instruction code */
682 lda t0,-0x177b(t0) /* test for LDAH */
684 ldl t0,4(ra) /* load instruction LDAH PV,xxx(RA) */
685 sll t0,16,t0 /* compute high offset */
686 addl t0,0,t0 /* sign extend high offset */
687 addq t0,pv,pv /* compute update address */
690 .end asm_handle_nat_exception
693 /* asm_wrapper_patcher *********************************************************
698 32 return address into JIT code (patch position)
699 24 pointer to virtual java_objectheader
700 16 machine code (which is patched back later)
701 8 unresolved class/method/field reference
702 0 patcher function pointer to call (pv afterwards)
704 ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
706 *******************************************************************************/
708 .ent asm_wrapper_patcher
711 lda sp,-((12+27+4)*8+sizestackframeinfo)(sp) /* create stack frame */
713 SAVE_ARGUMENT_REGISTERS(0) /* save 6 int/6 float argument registers */
714 SAVE_TEMPORARY_REGISTERS(12) /* save 11 int/16 float temporary registers */
716 stq itmp1,(12+27+0)*8(sp) /* save itmp1 */
717 stq itmp2,(12+27+1)*8(sp) /* save itmp2 */
718 stq ra,(12+27+2)*8(sp) /* save method return address (for leafs) */
719 stq pv,(12+27+3)*8(sp) /* save pv of calling java function */
721 br ra,L_asm_wrapper_patcher_load_gp
722 L_asm_wrapper_patcher_load_gp:
723 ldgp gp,0(ra) /* load gp (it's not set correctly in jit) */
725 lda a0,(12+27+4)*8(sp) /* create stackframe info */
726 mov pv,a1 /* pass java pv */
727 lda a2,((5+12+27+4)*8+sizestackframeinfo)(sp) /* pass java sp */
728 ldq a3,(12+27+2)*8(sp) /* this is correct for leafs */
729 ldq a4,((4+12+27+4)*8+sizestackframeinfo)(sp) /* pass xpc */
730 jsr ra,stacktrace_create_extern_stackframeinfo
733 lda a0,((0+12+27+4)*8+sizestackframeinfo)(sp) /* pass sp */
734 ldq pv,((0+12+27+4)*8+sizestackframeinfo)(sp) /* get function pointer */
735 ldq itmp1,(12+27+3)*8(sp) /* save pv to the position of fp */
736 stq itmp1,((0+12+27+4)*8+sizestackframeinfo)(sp)
737 jmp ra,(pv) /* call the patcher function */
740 lda a0,(12+27+4)*8(sp) /* remove stackframe info */
741 jsr ra,stacktrace_remove_stackframeinfo
744 RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
745 RESTORE_TEMPORARY_REGISTERS(12)/* restore 11 integer temporary registers */
747 ldq itmp1,(12+27+0)*8(sp) /* restore itmp1 */
748 ldq itmp2,(12+27+1)*8(sp) /* restore itmp2 */
749 ldq ra,(12+27+2)*8(sp) /* restore method return address (for leafs)*/
750 ldq pv,(12+27+3)*8(sp) /* restore pv of calling java function */
752 ldq itmp3,((4+12+27+4)*8+sizestackframeinfo)(sp)/* get RA to jit code */
753 lda sp,((5+12+27+4)*8+sizestackframeinfo)(sp) /* remove stack frame */
755 beq v0,L_asm_wrapper_patcher_exception
757 jmp zero,(itmp3) /* jump to new patched code */
759 L_asm_wrapper_patcher_exception:
760 mov itmp3,xpc /* return address into JIT code is xpc */
762 br itmp1,L_asm_wrapper_patcher_exception_load_gp
763 L_asm_wrapper_patcher_exception_load_gp:
764 ldgp gp,0(itmp1) /* itmp3 == gp, load the current gp */
766 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
768 stq xpc,0*8(sp) /* save return address (xpc) */
771 jsr ra,builtin_asm_get_exceptionptrptr
772 ldq xpc,0*8(sp) /* restore return address (xpc) */
779 ldq xptr,0(v0) /* get the exception pointer */
780 stq zero,0(v0) /* clear the exception pointer */
781 br asm_handle_exception /* we have the pv of the calling java func. */
783 .end asm_wrapper_patcher
786 /******************* function asm_initialize_thread_stack **********************
788 * initialized a thread stack *
790 *******************************************************************************/
792 .ent asm_initialize_thread_stack
794 asm_initialize_thread_stack:
815 .end asm_initialize_thread_stack
818 /******************* function asm_perform_threadswitch *************************
820 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
822 * performs a threadswitch *
824 *******************************************************************************/
826 .ent asm_perform_threadswitch
828 asm_perform_threadswitch:
869 .end asm_perform_threadswitch
872 /********************* function asm_switchstackandcall *************************
874 * void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
877 * Switches to a new stack, calls a function and switches back. *
878 * a0 new stack pointer *
879 * a1 function pointer *
880 * a2 pointer to variable where stack top should be stored *
881 * a3 pointer to user data, is passed to the function *
883 *******************************************************************************/
886 .ent asm_switchstackandcall
888 asm_switchstackandcall:
889 lda a0,-2*8(a0) /* allocate new stack */
890 stq ra,0(a0) /* save return address on new stack */
891 stq sp,1*8(a0) /* save old stack pointer on new stack */
892 stq sp,0(a2) /* save old stack pointer to variable */
893 mov a0,sp /* switch to new stack */
895 mov a1,pv /* load function pointer */
896 mov a3,a0 /* pass pointer */
897 jmp ra,(pv) /* and call function */
899 ldq ra,0(sp) /* load return address */
900 ldq sp,1*8(sp) /* switch to old stack */
902 jmp zero,(ra) /* return */
904 .end asm_switchstackandcall
906 .ent asm_getclassvalues_atomic
908 asm_getclassvalues_atomic:
911 ldl t0,offbaseval(a0)
912 ldl t1,offdiffval(a0)
913 ldl t2,offbaseval(a1)
915 stl t0,offcast_super_baseval(a2)
916 stl t1,offcast_super_diffval(a2)
917 stl t2,offcast_sub_baseval(a2)
920 .end asm_getclassvalues_atomic
924 asm_criticalsections:
925 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
937 * These are local overrides for various environment variables in Emacs.
938 * Please do not remove this and leave it at the end of the file, where
939 * Emacs will automagically detect them.
940 * ---------------------------------------------------------------------
943 * indent-tabs-mode: t