--- /dev/null
+/* -*- mode: asm; tab-width: 4 -*- */
+/****************************** asmpart.c **************************************
+* *
+* is an assembly language file, but called .c to fake the preprocessor. *
+* It contains the Java-C interface functions for Alpha processors. *
+* *
+* Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst *
+* *
+* See file COPYRIGHT for information on usage and disclaimer of warranties *
+* *
+* Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at *
+* Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at *
+* *
+* Last Change: 1998/11/01 *
+* *
+*******************************************************************************/
+
+#include "offsets.h"
+
+#define v0 $0
+
+#define t0 $1
+#define t1 $2
+#define t2 $3
+#define t3 $4
+#define t4 $5
+#define t5 $6
+#define t6 $7
+#define t7 $8
+
+#define s0 $9
+#define s1 $10
+#define s2 $11
+#define s3 $12
+#define s4 $13
+#define s5 $14
+#define s6 $15
+
+#define a0 $16
+#define a1 $17
+#define a2 $18
+#define a3 $19
+#define a4 $20
+#define a5 $21
+
+#define t8 $22
+#define t9 $23
+#define t10 $24
+#define t11 $25
+#define ra $26
+#define t12 $27
+
+#define pv t12
+#define AT $at
+#define gp $29
+#define sp $30
+#define zero $31
+
+#define itmp1 $25
+#define itmp2 $28
+#define itmp3 $29
+
+#define xptr itmp1
+#define xpc itmp2
+
+#define sf0 $f2
+#define sf1 $f3
+#define sf2 $f4
+#define sf3 $f5
+#define sf4 $f6
+#define sf5 $f7
+#define sf6 $f8
+#define sf7 $f9
+
+#define fzero $f31
+
+
+#define PAL_imb 134
+
+ .text
+ .set noat
+ .set noreorder
+
+
+/********************* exported functions and variables ***********************/
+
+ .globl has_no_x_instr_set
+ .globl synchronize_caches
+ .globl asm_calljavamethod
+ .globl asm_calljavafunction
+ .globl asm_call_jit_compiler
+ .globl asm_dumpregistersandcall
+ .globl asm_handle_exception
+ .globl asm_handle_nat_exception
+ .globl asm_builtin_checkcast
+ .globl asm_builtin_checkarraycast
+ .globl asm_builtin_aastore
+ .globl asm_builtin_monitorenter
+ .globl asm_builtin_monitorexit
+ .globl asm_builtin_idiv
+ .globl asm_builtin_irem
+ .globl asm_builtin_ldiv
+ .globl asm_builtin_lrem
+ .globl asm_perform_threadswitch
+ .globl asm_initialize_thread_stack
+ .globl asm_switchstackandcall
+ .globl asm_getcallingmethod
+
+/*************************** imported variables *******************************/
+
+ .globl newcompiler
+
+
+/*************************** imported functions *******************************/
+
+ .globl jit_compile
+ .globl builtin_monitorexit
+ .globl builtin_throw_exception
+ .globl builtin_trace_exception
+ .globl class_java_lang_Object
+
+
+/*********************** function has_no_x_instr_set ***************************
+* *
+* determines if the byte support instruction set (21164a and higher) *
+* is available. *
+* *
+*******************************************************************************/
+
+ .ent has_no_x_instr_set
+has_no_x_instr_set:
+
+ .long 0x47e03c20 /* amask 1,v0 */
+ jmp zero,(ra) /* return */
+
+ .end has_no_x_instr_set
+
+
+/********************* function synchronize_caches ****************************/
+
+ .ent synchronize_caches
+synchronize_caches:
+
+ call_pal PAL_imb /* synchronise instruction cache */
+ jmp zero,(ra) /* return */
+
+ .end synchronize_caches
+
+
+/********************* function asm_calljavamethod *****************************
+* *
+* This function calls a Java-method (which possibly needs compilation) *
+* with up to 4 parameters. *
+* *
+* This functions calls the JIT-compiler which eventually translates the *
+* method into machine code. *
+* *
+* An possibly throwed exception will be returned to the caller as function *
+* return value, so the java method cannot return a fucntion value (this *
+* function usually calls 'main' and '<clinit>' which do not return a *
+* function value). *
+* *
+* C-prototype: *
+* javaobject_header *asm_calljavamethod (methodinfo *m, *
+* void *arg1, void *arg2, void *arg3, void *arg4); *
+* *
+*******************************************************************************/
+
+#define MethodPointer -8
+#define FrameSize -12
+#define IsSync -16
+#define IsLeaf -20
+#define IntSave -24
+#define FltSave -28
+#define ExTableSize -32
+#define ExTableStart -32
+
+#define ExEntrySize -32
+#define ExStartPC -8
+#define ExEndPC -16
+#define ExHandlerPC -24
+#define ExCatchType -32
+
+ .ent asm_calljavamethod
+
+call_name:
+ .ascii "calljavamethod\0\0"
+
+ .align 3
+ .quad 0 /* catch type all */
+ .quad calljava_xhandler /* handler pc */
+ .quad calljava_xhandler /* end pc */
+ .quad asm_calljavamethod /* start pc */
+ .long 1 /* extable size */
+ .long 0 /* fltsave */
+ .long 0 /* intsave */
+ .long 0 /* isleaf */
+ .long 0 /* IsSync */
+ .long 32 /* frame size */
+ .quad 0 /* method pointer (pointer to name) */
+
+asm_calljavamethod:
+
+ ldgp gp,0(pv)
+ lda sp,-32(sp) /* allocate stack space */
+ stq gp,24(sp) /* save global pointer */
+ stq ra,0(sp) /* save return address */
+
+ stq a0,16(sp) /* save method pointer for compiler */
+ lda v0,16(sp) /* pass pointer to method pointer via v0*/
+
+ mov a1,a0 /* pass the remaining parameters */
+ mov a2,a1
+ mov a3,a2
+ mov a4,a3
+
+ lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
+ stq $28,8(sp) /* store function address */
+ mov sp,$28 /* set method pointer */
+
+ ldq pv,8($28) /* method call as in Java */
+ jmp ra,(pv) /* call JIT compiler */
+calljava_jit:
+ lda pv,-64(ra) /* asm_calljavamethod-calljava_jit !!!!!*/
+
+calljava_return:
+
+ ldq ra,0(sp) /* restore return address */
+ ldq gp,24(sp) /* restore global pointer */
+ lda sp,32(sp) /* free stack space */
+ ldl v0,newcompiler /* load newcompiler flag */
+ subq v0,1,v0 /* negate for clearing v0 */
+ beq v0,calljava_ret /* if newcompiler skip ex copying */
+ mov $1,v0 /* pass exception to caller (C) */
+calljava_ret:
+ jmp zero,(ra)
+
+calljava_xhandler:
+
+ ldq gp,24(sp) /* restore global pointer */
+ mov itmp1,a0
+ jsr ra,builtin_throw_exception
+ ldq ra,0(sp) /* restore return address */
+ lda sp,32(sp) /* free stack space */
+ jmp zero,(ra)
+ .end asm_calljavamethod
+
+
+/********************* function asm_calljavafunction ***************************
+* *
+* This function calls a Java-method (which possibly needs compilation) *
+* with up to 4 address parameters. *
+* *
+* This functions calls the JIT-compiler which eventually translates the *
+* method into machine code. *
+* *
+* C-prototype: *
+* javaobject_header *asm_calljavamethod (methodinfo *m, *
+* void *arg1, void *arg2, void *arg3, void *arg4); *
+* *
+*******************************************************************************/
+
+ .ent asm_calljavafunction
+
+call_name2:
+ .ascii "calljavafunction\0\0"
+
+ .align 3
+ .quad 0 /* catch type all */
+ .quad calljava_xhandler2 /* handler pc */
+ .quad calljava_xhandler2 /* end pc */
+ .quad asm_calljavafunction /* start pc */
+ .long 1 /* extable size */
+ .long 0 /* fltsave */
+ .long 0 /* intsave */
+ .long 0 /* isleaf */
+ .long 0 /* IsSync */
+ .long 32 /* frame size */
+ .quad 0 /* method pointer (pointer to name) */
+
+asm_calljavafunction:
+
+ ldgp gp,0(pv)
+ lda sp,-32(sp) /* allocate stack space */
+ stq gp,24(sp) /* save global pointer */
+ stq ra,0(sp) /* save return address */
+
+ stq a0,16(sp) /* save method pointer for compiler */
+ lda v0,16(sp) /* pass pointer to method pointer via v0*/
+
+ mov a1,a0 /* pass the remaining parameters */
+ mov a2,a1
+ mov a3,a2
+ mov a4,a3
+
+ lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
+ stq $28,8(sp) /* store function address */
+ mov sp,$28 /* set method pointer */
+
+ ldq pv,8($28) /* method call as in Java */
+ jmp ra,(pv) /* call JIT compiler */
+calljava_jit2:
+ lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
+
+calljava_return2:
+
+ ldq ra,0(sp) /* restore return address */
+ ldq gp,24(sp) /* restore global pointer */
+ lda sp,32(sp) /* free stack space */
+
+/* ldl v0,newcompiler */ /* load newcompiler flag */
+/* subq v0,1,v0 */ /* negate for clearing v0 */
+/* beq v0,calljava_ret*/ /* if newcompiler skip ex copying */
+/* mov $1,v0 */ /* pass exception to caller (C) */
+calljava_ret2:
+ jmp zero,(ra)
+
+calljava_xhandler2:
+
+ ldq gp,24(sp) /* restore global pointer */
+ mov itmp1,a0
+ jsr ra,builtin_throw_exception
+ ldq ra,0(sp) /* restore return address */
+ lda sp,32(sp) /* free stack space */
+ jmp zero,(ra)
+ .end asm_calljavafunction
+
+
+/****************** function asm_call_jit_compiler *****************************
+* *
+* invokes the compiler for untranslated JavaVM methods. *
+* *
+* Register R0 contains a pointer to the method info structure (prepared *
+* by createcompilerstub). Using the return address in R26 and the *
+* offset in the LDA instruction or using the value in methodptr R28 the *
+* patching address for storing the method address can be computed: *
+* *
+* method address was either loaded using *
+* M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
+* M_LDA (REG_PV, REG_RA, low) *
+* M_LDAH(REG_PV, REG_RA, high) ; optional *
+* or *
+* M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
+* in the static case the method pointer can be computed using the *
+* return address and the lda function following the jmp instruction *
+* *
+*******************************************************************************/
+
+
+ .ent asm_call_jit_compiler
+asm_call_jit_compiler:
+
+ ldgp gp,0(pv)
+ ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
+ srl t8,16,t8 /* shift right register number $yy */
+ and t8,31,t8 /* isolate register number */
+ subl t8,28,t8 /* test for REG_METHODPTR */
+ beq t8,noregchange
+ ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t8,48,t8
+ sra t8,48,t8 /* isolate offset */
+ addq t8,ra,$28 /* compute update address */
+ ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
+ srl t8,16,t8 /* isolate instruction code */
+ lda t8,-0x177b(t8) /* test for LDAH */
+ bne t8,noregchange
+ ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
+ sll t8,16,t8 /* compute high offset */
+ addl t8,0,t8 /* sign extend high offset */
+ addq t8,$28,$28 /* compute update address */
+noregchange:
+ lda sp,-14*8(sp) /* reserve stack space */
+ stq a0,0*8(sp) /* save all argument registers */
+ stq a1,1*8(sp) /* they could be used by method */
+ stq a2,2*8(sp)
+ stq a3,3*8(sp)
+ stq a4,4*8(sp)
+ stq a5,5*8(sp)
+ stt $f16,6*8(sp)
+ stt $f17,7*8(sp)
+ stt $f18,8*8(sp)
+ stt $f19,9*8(sp)
+ stt $f20,10*8(sp)
+ stt $f21,11*8(sp)
+ stq $28,12*8(sp) /* save method pointer */
+ stq ra,13*8(sp) /* save return address */
+
+ ldq a0,0(v0) /* pass 'methodinfo' pointer to */
+ jsr ra,jit_compile /* jit compiler */
+ ldgp gp,0(ra)
+
+ call_pal PAL_imb /* synchronise instruction cache */
+
+ ldq a0,0*8(sp) /* load argument registers */
+ ldq a1,1*8(sp)
+ ldq a2,2*8(sp)
+ ldq a3,3*8(sp)
+ ldq a4,4*8(sp)
+ ldq a5,5*8(sp)
+ ldt $f16,6*8(sp)
+ ldt $f17,7*8(sp)
+ ldt $f18,8*8(sp)
+ ldt $f19,9*8(sp)
+ ldt $f20,10*8(sp)
+ ldt $f21,11*8(sp)
+ ldq $28,12*8(sp) /* load method pointer */
+ ldq ra,13*8(sp) /* load return address */
+ lda sp,14*8(sp) /* deallocate stack area */
+
+ ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
+ sll t8,48,t8
+ sra t8,48,t8 /* isolate offset */
+
+ addq t8,$28,t8 /* compute update address via method pointer*/
+ stq v0,0(t8) /* save new method address there */
+
+ mov v0,pv /* load method address into pv */
+
+ jmp zero,(pv) /* and call method. The method returns */
+ /* directly to the caller (ra). */
+
+ .end asm_call_jit_compiler
+
+
+/****************** function asm_dumpregistersandcall **************************
+* *
+* This funtion saves all callee saved registers and calls the function *
+* which is passed as parameter. *
+* *
+* This function is needed by the garbage collector, which needs to access *
+* all registers which are stored on the stack. Unused registers are *
+* cleared to avoid interferances with the GC. *
+* *
+* void asm_dumpregistersandcall (functionptr f); *
+* *
+*******************************************************************************/
+
+ .ent asm_dumpregistersandcall
+asm_dumpregistersandcall:
+ lda sp,-16*8(sp) /* allocate stack */
+ stq ra,0(sp) /* save return address */
+
+ stq s0,1*8(sp) /* save all callee saved registers */
+ stq s1,2*8(sp) /* intialize the remaining registers */
+ stq s2,3*8(sp)
+ stq s3,4*8(sp)
+ stq s4,5*8(sp)
+ stq s5,6*8(sp)
+ stq s6,7*8(sp)
+ stt $f2,8*8(sp)
+ stt $f3,9*8(sp)
+ stt $f4,10*8(sp)
+ stt $f5,11*8(sp)
+ stt $f6,12*8(sp)
+ stt $f7,13*8(sp)
+ stt $f8,14*8(sp)
+ stt $f9,15*8(sp)
+
+ clr v0 /* intialize the remaining registers */
+ clr t0
+ clr t1
+ clr t2
+ clr t3
+ clr t4
+ clr t5
+ clr t6
+ clr t7
+ clr a1
+ clr a2
+ clr a3
+ clr a4
+ clr a5
+ clr t8
+ clr t9
+ clr t10
+ clr t11
+ clr t12
+ clr $28
+ clr $29
+ cpys $f31,$f31,$f0
+ cpys $f31,$f31,$f1
+ cpys $f31,$f31,$f10
+ cpys $f31,$f31,$f11
+ cpys $f31,$f31,$f12
+ cpys $f31,$f31,$f13
+ cpys $f31,$f31,$f14
+ cpys $f31,$f31,$f15
+ cpys $f31,$f31,$f16
+ cpys $f31,$f31,$f17
+ cpys $f31,$f31,$f18
+ cpys $f31,$f31,$f19
+ cpys $f31,$f31,$f20
+ cpys $f31,$f31,$f21
+ cpys $f31,$f31,$f22
+ cpys $f31,$f31,$f23
+ cpys $f31,$f31,$f24
+ cpys $f31,$f31,$f25
+ cpys $f31,$f31,$f26
+ cpys $f31,$f31,$f27
+ cpys $f31,$f31,$f28
+ cpys $f31,$f31,$f29
+ cpys $f31,$f31,$f30
+
+ mov a0,pv /* load function pointer */
+ jmp ra,(pv) /* and call function */
+
+ ldq ra,0(sp) /* load return address */
+ lda sp,16*8(sp) /* deallocate stack */
+ jmp zero,(ra) /* return */
+
+ .end asm_dumpregistersandcall
+
+
+/********************* function asm_handle_exception ***************************
+* *
+* This function handles an exception. It does not use the usual calling *
+* conventions. The exception pointer is passed in REG_ITMP1 and the *
+* pc from the exception raising position is passed in REG_ITMP2. It searches *
+* the local exception table for a handler. If no one is found, it unwinds *
+* stacks and continues searching the callers. *
+* *
+* void asm_handle_exception (exceptionptr, exceptionpc); *
+* *
+*******************************************************************************/
+
+ .ent asm_handle_nat_exception
+asm_handle_nat_exception:
+
+ ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,48,t0
+ sra t0,48,t0 /* isolate offset */
+ addq t0,ra,pv /* compute update address */
+ ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
+ srl t0,16,t0 /* isolate instruction code */
+ lda t0,-0x177b(t0) /* test for LDAH */
+ bne t0,asm_handle_exception
+ ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
+ sll t0,16,t0 /* compute high offset */
+ addl t0,0,t0 /* sign extend high offset */
+ addq t0,pv,pv /* compute update address */
+
+ .aent asm_handle_exception
+asm_handle_exception:
+
+ lda sp,-18*8(sp) /* allocate stack */
+ stq t0,0*8(sp) /* save possible used registers */
+ stq t1,1*8(sp) /* also registers used by trace_exception */
+ stq t2,2*8(sp)
+ stq t3,3*8(sp)
+ stq t4,4*8(sp)
+ stq t5,5*8(sp)
+ stq t6,6*8(sp)
+ stq t7,7*8(sp)
+ stq t8,8*8(sp)
+ stq t9,9*8(sp)
+ stq t10,10*8(sp)
+ stq v0,11*8(sp)
+ stq a0,12*8(sp)
+ stq a1,13*8(sp)
+ stq a2,14*8(sp)
+ stq a3,15*8(sp)
+ stq a4,16*8(sp)
+ stq a5,17*8(sp)
+
+ lda t3,1(zero) /* set no unwind flag */
+ex_stack_loop:
+ lda sp,-5*8(sp) /* allocate stack */
+ stq xptr,0*8(sp) /* save used register */
+ stq xpc,1*8(sp)
+ stq pv,2*8(sp)
+ stq ra,3*8(sp)
+ stq t3,4*8(sp)
+
+ mov xptr,a0
+ ldq a1,MethodPointer(pv)
+ mov xpc,a2
+ mov t3,a3
+ br ra,ex_trace /* set ra for gp loading */
+ex_trace:
+ ldgp gp,0(ra) /* load gp */
+ jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
+
+ ldq xptr,0*8(sp) /* restore used register */
+ ldq xpc,1*8(sp)
+ ldq pv,2*8(sp)
+ ldq ra,3*8(sp)
+ ldq t3,4*8(sp)
+ lda sp,5*8(sp) /* deallocate stack */
+
+ ldl t0,ExTableSize(pv) /* t0 = exception table size */
+ beq t0,empty_table /* if empty table skip */
+ lda t1,ExTableStart(pv) /* t1 = start of exception table */
+
+ex_table_loop:
+ ldq t2,ExStartPC(t1) /* t2 = exception start pc */
+ cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
+ beq t2,ex_table_cont /* if (false) continue */
+ ldq t2,ExEndPC(t1) /* t2 = exception end pc */
+ cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
+ beq t2,ex_table_cont /* if (false) continue */
+ ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
+ beq a1,ex_handle_it /* NULL catches everything */
+
+ ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
+ ldq a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
+ ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
+ ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
+ ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
+ subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
+ cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
+ beq v0,ex_table_cont /* if (false) continue */
+
+ex_handle_it:
+
+ ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
+
+ beq t3,ex_jump /* if (!(no stack unwinding) skip */
+
+ ldq t0,0*8(sp) /* restore possible used registers */
+ ldq t1,1*8(sp) /* also registers used by trace_exception */
+ ldq t2,2*8(sp)
+ ldq t3,3*8(sp)
+ ldq t4,4*8(sp)
+ ldq t5,5*8(sp)
+ ldq t6,6*8(sp)
+ ldq t7,7*8(sp)
+ ldq t8,8*8(sp)
+ ldq t9,9*8(sp)
+ ldq t10,10*8(sp)
+ ldq v0,11*8(sp)
+ ldq a0,12*8(sp)
+ ldq a1,13*8(sp)
+ ldq a2,14*8(sp)
+ ldq a3,15*8(sp)
+ ldq a4,16*8(sp)
+ ldq a5,17*8(sp)
+ lda sp,18*8(sp) /* deallocate stack */
+
+ex_jump:
+ jmp zero,(xpc) /* jump to the handler */
+
+ex_table_cont:
+ lda t1,ExEntrySize(t1) /* next exception table entry */
+ subl t0,1,t0 /* decrement entry counter */
+ bgt t0,ex_table_loop /* if (t0 > 0) next entry */
+
+empty_table:
+ beq t3,ex_already_cleared /* if here the first time, then */
+ lda sp,18*8(sp) /* deallocate stack and */
+ clr t3 /* clear the no unwind flag */
+ex_already_cleared:
+ ldl t0,IsSync(pv) /* t0 = SyncOffset */
+ beq t0,no_monitor_exit /* if zero no monitorexit */
+ addq sp,t0,t0 /* add stackptr to Offset */
+ ldq a0,-8(t0) /* load monitorexit pointer */
+
+ lda sp,-7*8(sp) /* allocate stack */
+ stq t0,0*8(sp) /* save used register */
+ stq t1,1*8(sp)
+ stq t3,2*8(sp)
+ stq xptr,3*8(sp)
+ stq xpc,4*8(sp)
+ stq pv,5*8(sp)
+ stq ra,6*8(sp)
+
+ br ra,ex_mon_load /* set ra for gp loading */
+ex_mon_load:
+ ldgp gp,0(ra) /* load gp */
+ jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
+
+ ldq t0,0*8(sp) /* restore used register */
+ ldq t1,1*8(sp)
+ ldq t3,2*8(sp)
+ ldq xptr,3*8(sp)
+ ldq xpc,4*8(sp)
+ ldq pv,5*8(sp)
+ ldq ra,6*8(sp)
+ lda sp,7*8(sp) /* deallocate stack */
+
+no_monitor_exit:
+ ldl t0,FrameSize(pv) /* t0 = frame size */
+ addq sp,t0,sp /* unwind stack */
+ mov sp,t0 /* t0 = pointer to save area */
+ ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
+ bne t1,ex_no_restore /* if (leaf) skip */
+ ldq ra,-8(t0) /* restore ra */
+ lda t0,-8(t0) /* t0-- */
+ex_no_restore:
+ mov ra,xpc /* the new xpc is ra */
+ ldl t1,IntSave(pv) /* t1 = saved int register count */
+ br t2,ex_int1 /* t2 = current pc */
+ex_int1:
+ lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
+ negl t1,t1 /* negate register count */
+ s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
+ jmp zero,(t2) /* jump to save position */
+ ldq s0,-56(t0)
+ ldq s1,-48(t0)
+ ldq s2,-40(t0)
+ ldq s3,-32(t0)
+ ldq s4,-24(t0)
+ ldq s5,-16(t0)
+ ldq s6,-8(t0)
+ex_int2:
+ s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
+
+ ldl t1,FltSave(pv) /* t1 = saved flt register count */
+ br t2,ex_flt1 /* t2 = current pc */
+ex_flt1:
+ lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
+ negl t1,t1 /* negate register count */
+ s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
+ jmp zero,(t2) /* jump to save position */
+ ldt $f2,-64(t0)
+ ldt $f3,-56(t0)
+ ldt $f4,-48(t0)
+ ldt $f5,-40(t0)
+ ldt $f6,-32(t0)
+ ldt $f7,-24(t0)
+ ldt $f8,-16(t0)
+ ldt $f9,-8(t0)
+ex_flt2:
+ ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,48,t0
+ sra t0,48,t0 /* isolate offset */
+ addq t0,ra,pv /* compute update address */
+ ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
+ srl t0,16,t0 /* isolate instruction code */
+ lda t0,-0x177b(t0) /* test for LDAH */
+ bne t0,ex_stack_loop
+ ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,16,t0 /* compute high offset */
+ addl t0,0,t0 /* sign extend high offset */
+ addq t0,pv,pv /* compute update address */
+ br ex_stack_loop
+
+ .end asm_handle_nat_exception
+
+
+/********************* function asm_builtin_monitorenter ***********************
+* *
+* Does null check and calls monitorenter or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_monitorenter
+asm_builtin_monitorenter:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_monitorenter
+ beq a0,nb_monitorenter /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_monitorenter */
+
+nb_monitorenter:
+ ldq xptr,proto_java_lang_NullPointerException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_monitorenter
+
+
+/********************* function asm_builtin_monitorexit ************************
+* *
+* Does null check and calls monitorexit or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_monitorexit
+asm_builtin_monitorexit:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_monitorexit
+ beq a0,nb_monitorexit /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_monitorexit */
+
+nb_monitorexit:
+ ldq xptr,proto_java_lang_NullPointerException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_monitorexit
+
+
+/************************ function asm_builtin_idiv ****************************
+* *
+* Does null check and calls idiv or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_idiv
+asm_builtin_idiv:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_idiv
+ beq a1,nb_idiv /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_idiv */
+
+nb_idiv:
+ ldq xptr,proto_java_lang_ArithmeticException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_idiv
+
+
+/************************ function asm_builtin_ldiv ****************************
+* *
+* Does null check and calls ldiv or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_ldiv
+asm_builtin_ldiv:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_ldiv
+ beq a1,nb_ldiv /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_ldiv */
+
+nb_ldiv:
+ ldq xptr,proto_java_lang_ArithmeticException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_ldiv
+
+
+/************************ function asm_builtin_irem ****************************
+* *
+* Does null check and calls irem or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_irem
+asm_builtin_irem:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_irem
+ beq a1,nb_irem /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_irem */
+
+nb_irem:
+ ldq xptr,proto_java_lang_ArithmeticException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_irem
+
+
+/************************ function asm_builtin_lrem ****************************
+* *
+* Does null check and calls lrem or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_lrem
+asm_builtin_lrem:
+
+ ldgp gp,0(pv)
+ lda pv,builtin_lrem
+ beq a1,nb_lrem /* if (null) throw exception */
+ jmp zero,(pv) /* else call builtin_lrem */
+
+nb_lrem:
+ ldq xptr,proto_java_lang_ArithmeticException
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_lrem
+
+
+ /*********************** function new_builtin_checkcast ************************
+ * *
+ * Does the cast check and eventually throws an exception *
+ * *
+ *******************************************************************************/
+
+ .ent asm_builtin_checkcast
+asm_builtin_checkcast:
+
+ ldgp gp,0(pv)
+ lda sp,-16(sp) # allocate stack space
+ stq ra,0(sp) # save return address
+ stq a0,8(sp) # save object pointer
+ jsr ra,builtin_checkcast # builtin_checkcast
+ ldgp gp,0(ra)
+ beq v0,nb_ccast_throw # if (false) throw exception
+ ldq ra,0(sp) # restore return address
+ ldq v0,8(sp) # return object pointer
+ lda sp,16(sp) # free stack space
+ jmp zero,(ra)
+
+nb_ccast_throw:
+ ldq xptr,proto_java_lang_ClassCastException
+ ldq ra,0(sp) # restore return address
+ lda sp,16(sp) # free stack space
+ lda xpc,-4(ra) # faulting address is return adress - 4
+ br asm_handle_nat_exception
+ .end asm_builtin_checkcast
+
+
+/******************* function asm_builtin_checkarraycast ***********************
+* *
+* Does the cast check and eventually throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_checkarraycast
+asm_builtin_checkarraycast:
+
+ ldgp gp,0(pv)
+ lda sp,-16(sp) /* allocate stack space */
+ stq ra,0(sp) /* save return address */
+ stq a0,8(sp) /* save object pointer */
+ jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
+ ldgp gp,0(ra)
+ beq v0,nb_carray_throw /* if (false) throw exception */
+ ldq ra,0(sp) /* restore return address */
+ ldq v0,8(sp) /* return object pointer */
+ lda sp,16(sp) /* free stack space */
+ jmp zero,(ra)
+
+nb_carray_throw:
+ ldq xptr,proto_java_lang_ClassCastException
+ ldq ra,0(sp) /* restore return address */
+ lda sp,16(sp) /* free stack space */
+ lda xpc,-4(ra) /* faulting address is return adress - 4*/
+ br asm_handle_nat_exception
+ .end asm_builtin_checkarraycast
+
+
+/******************* function asm_builtin_aastore ******************************
+* *
+* Does the cast check and eventually throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_aastore
+asm_builtin_aastore:
+
+ ldgp gp,0(pv)
+ beq a0,nb_aastore_null /* if null pointer throw exception */
+ ldl t0,offarraysize(a0) /* load size */
+ lda sp,-24(sp) /* allocate stack space */
+ stq ra,0(sp) /* save return address */
+ s8addq a1,a0,t1 /* add index*8 to arrayref */
+ cmpult a1,t0,t0 /* do bound check */
+ beq t0,nb_aastore_bound /* if out of bounds throw exception */
+ mov a2,a1 /* object is second argument */
+ stq t1,8(sp) /* save store position */
+ stq a1,16(sp) /* save object */
+ jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
+ ldgp gp,0(ra)
+ ldq ra,0(sp) /* restore return address */
+ ldq a0,8(sp) /* restore store position */
+ ldq a1,16(sp) /* restore object */
+ lda sp,24(sp) /* free stack space */
+ beq v0,nb_aastore_throw /* if (false) throw exception */
+ stq a1,offobjarrdata(a0) /* store objectptr in array */
+ jmp zero,(ra)
+
+nb_aastore_null:
+ ldq xptr,proto_java_lang_NullPointerException
+ mov ra,xpc /* faulting address is return adress */
+ br asm_handle_nat_exception
+
+nb_aastore_bound:
+ ldq xptr,proto_java_lang_ArrayIndexOutOfBoundsException
+ lda sp,24(sp) /* free stack space */
+ mov ra,xpc /* faulting address is return adress */
+ br asm_handle_nat_exception
+
+nb_aastore_throw:
+ ldq xptr,proto_java_lang_ArrayStoreException
+ mov ra,xpc /* faulting address is return adress */
+ br asm_handle_nat_exception
+
+ .end asm_builtin_aastore
+
+
+/******************* function asm_initialize_thread_stack **********************
+* *
+* initialized a thread stack *
+* *
+*******************************************************************************/
+
+ .ent asm_initialize_thread_stack
+asm_initialize_thread_stack:
+
+ lda a1,-128(a1)
+ stq zero, 0(a1)
+ stq zero, 8(a1)
+ stq zero, 16(a1)
+ stq zero, 24(a1)
+ stq zero, 32(a1)
+ stq zero, 40(a1)
+ stq zero, 48(a1)
+ stt fzero, 56(a1)
+ stt fzero, 64(a1)
+ stt fzero, 72(a1)
+ stt fzero, 80(a1)
+ stt fzero, 88(a1)
+ stt fzero, 96(a1)
+ stt fzero, 104(a1)
+ stt fzero, 112(a1)
+ stq a0, 120(a1)
+ mov a1, v0
+ jmp zero,(ra)
+ .end asm_initialize_thread_stack
+
+
+/******************* function asm_perform_threadswitch *************************
+* *
+* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
+* *
+* performs a threadswitch *
+* *
+*******************************************************************************/
+
+ .ent asm_perform_threadswitch
+asm_perform_threadswitch:
+
+ subq sp,128,sp
+ stq s0, 0(sp)
+ stq s1, 8(sp)
+ stq s2, 16(sp)
+ stq s3, 24(sp)
+ stq s4, 32(sp)
+ stq s5, 40(sp)
+ stq s6, 48(sp)
+ stt sf0, 56(sp)
+ stt sf1, 64(sp)
+ stt sf2, 72(sp)
+ stt sf3, 80(sp)
+ stt sf4, 88(sp)
+ stt sf5, 96(sp)
+ stt sf6, 104(sp)
+ stt sf7, 112(sp)
+ stq ra, 120(sp)
+ stq sp, 0(a0)
+ stq sp, 0(a2)
+ ldq sp, 0(a1)
+ ldq s0, 0(sp)
+ ldq s1, 8(sp)
+ ldq s2, 16(sp)
+ ldq s3, 24(sp)
+ ldq s4, 32(sp)
+ ldq s5, 40(sp)
+ ldq s6, 48(sp)
+ ldt sf0, 56(sp)
+ ldt sf1, 64(sp)
+ ldt sf2, 72(sp)
+ ldt sf3, 80(sp)
+ ldt sf4, 88(sp)
+ ldt sf5, 96(sp)
+ ldt sf6, 104(sp)
+ ldt sf7, 112(sp)
+ ldq ra, 120(sp)
+ mov ra, pv
+ addq sp, 128, sp
+ jmp zero,(ra)
+ .end asm_perform_threadswitch
+
+
+/********************* function asm_switchstackandcall *************************
+* *
+* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
+* *
+* Switches to a new stack, calls a function and switches back. *
+* a0 new stack pointer *
+* a1 function pointer *
+* a2 pointer to variable where stack top should be stored *
+* *
+*******************************************************************************/
+
+
+ .ent asm_switchstackandcall
+asm_switchstackandcall:
+ lda a0,-2*8(a0) /* allocate new stack */
+ stq ra,0(a0) /* save return address on new stack */
+ stq sp,1*8(a0) /* save old stack pointer on new stack */
+ stq sp,0(a2) /* save old stack pointer to variable */
+ mov a0,sp /* switch to new stack */
+
+ mov a1,pv /* load function pointer */
+ jmp ra,(pv) /* and call function */
+
+ ldq ra,0(sp) /* load return address */
+ ldq sp,1*8(sp) /* switch to old stack */
+
+ jmp zero,(ra) /* return */
+
+ .end asm_switchstackandcall
+
+
+/********************* function asm_getcallingmethod ***************************
+* *
+* classinfo *asm_getcallingmethodclass (); *
+* *
+* goes back stack frames to get the calling method *
+* *
+* t2 .. sp *
+* t3 .. ra *
+* t4 .. pv *
+* *
+*******************************************************************************/
+
+
+ .ent asm_getcallingmethod
+asm_getcallingmethod:
+
+ ldq t3,16(sp) /* load return address of native function */
+ addq sp,24,t2 /* skip frames of C-Function and nativestub */
+
+ /* determine pv (t3) of java-function from ra */
+
+ ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
+ sll t0,48,t0
+ sra t0,48,t0 /* isolate offset */
+ addq t0,t3,t4 /* compute update address */
+ ldl t0,4(t3) /* load instruction LDAH PV,xxx(PV) */
+ srl t0,16,t0 /* isolate instruction code */
+ lda t0,-0x177b(t0) /* test for LDAH */
+ bne t0,pv_ok1
+ ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
+ sll t0,16,t0 /* compute high offset */
+ addl t0,0,t0 /* sign extend high offset */
+ addq t0,t4,t4 /* compute update address */
+
+pv_ok1:
+ ldl t0,FrameSize(t4) /* t0 = frame size */
+ addq t2,t0,t2 /* skip frame of java function */
+ ldq t3,-8(t2) /* load new ra */
+
+ /* determine pv (t3) of java-function from ra */
+
+ ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
+ sll t0,48,t0
+ sra t0,48,t0 /* isolate offset */
+ addq t0,t3,t4 /* compute update address */
+ ldl t0,4(t3) /* load instruction LDAH PV,xxx(PV) */
+ srl t0,16,t0 /* isolate instruction code */
+ lda t0,-0x177b(t0) /* test for LDAH */
+ bne t0,pv_ok2
+ ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
+ sll t0,16,t0 /* compute high offset */
+ addl t0,0,t0 /* sign extend high offset */
+ addq t0,t4,t4 /* compute update address */
+
+pv_ok2:
+ ldq v0,MethodPointer(t4) /* */
+
+
+ jmp zero,(ra) /* return */
+
+ .end asm_getcallingmethod
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+++ /dev/null
-/* -*- mode: asm; tab-width: 4 -*- */
-/****************************** asmpart.c **************************************
-* *
-* is an assembly language file, but called .c to fake the preprocessor. *
-* It contains the Java-C interface functions for Alpha processors. *
-* *
-* Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst *
-* *
-* See file COPYRIGHT for information on usage and disclaimer of warranties *
-* *
-* Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at *
-* Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at *
-* *
-* Last Change: 1998/11/01 *
-* *
-*******************************************************************************/
-
-#include "offsets.h"
-
-#define v0 $0
-
-#define t0 $1
-#define t1 $2
-#define t2 $3
-#define t3 $4
-#define t4 $5
-#define t5 $6
-#define t6 $7
-#define t7 $8
-
-#define s0 $9
-#define s1 $10
-#define s2 $11
-#define s3 $12
-#define s4 $13
-#define s5 $14
-#define s6 $15
-
-#define a0 $16
-#define a1 $17
-#define a2 $18
-#define a3 $19
-#define a4 $20
-#define a5 $21
-
-#define t8 $22
-#define t9 $23
-#define t10 $24
-#define t11 $25
-#define ra $26
-#define t12 $27
-
-#define pv t12
-#define AT $at
-#define gp $29
-#define sp $30
-#define zero $31
-
-#define itmp1 $25
-#define itmp2 $28
-#define itmp3 $29
-
-#define xptr itmp1
-#define xpc itmp2
-
-#define sf0 $f2
-#define sf1 $f3
-#define sf2 $f4
-#define sf3 $f5
-#define sf4 $f6
-#define sf5 $f7
-#define sf6 $f8
-#define sf7 $f9
-
-#define fzero $f31
-
-
-#define PAL_imb 134
-
- .text
- .set noat
- .set noreorder
-
-
-/********************* exported functions and variables ***********************/
-
- .globl has_no_x_instr_set
- .globl synchronize_caches
- .globl asm_calljavamethod
- .globl asm_calljavafunction
- .globl asm_call_jit_compiler
- .globl asm_dumpregistersandcall
- .globl asm_handle_exception
- .globl asm_handle_nat_exception
- .globl asm_builtin_checkcast
- .globl asm_builtin_checkarraycast
- .globl asm_builtin_aastore
- .globl asm_builtin_monitorenter
- .globl asm_builtin_monitorexit
- .globl asm_builtin_idiv
- .globl asm_builtin_irem
- .globl asm_builtin_ldiv
- .globl asm_builtin_lrem
- .globl asm_perform_threadswitch
- .globl asm_initialize_thread_stack
- .globl asm_switchstackandcall
- .globl asm_getcallingmethod
-
-/*************************** imported variables *******************************/
-
- .globl newcompiler
-
-
-/*************************** imported functions *******************************/
-
- .globl jit_compile
- .globl builtin_monitorexit
- .globl builtin_throw_exception
- .globl builtin_trace_exception
- .globl class_java_lang_Object
-
-
-/*********************** function has_no_x_instr_set ***************************
-* *
-* determines if the byte support instruction set (21164a and higher) *
-* is available. *
-* *
-*******************************************************************************/
-
- .ent has_no_x_instr_set
-has_no_x_instr_set:
-
- .long 0x47e03c20 /* amask 1,v0 */
- jmp zero,(ra) /* return */
-
- .end has_no_x_instr_set
-
-
-/********************* function synchronize_caches ****************************/
-
- .ent synchronize_caches
-synchronize_caches:
-
- call_pal PAL_imb /* synchronise instruction cache */
- jmp zero,(ra) /* return */
-
- .end synchronize_caches
-
-
-/********************* function asm_calljavamethod *****************************
-* *
-* This function calls a Java-method (which possibly needs compilation) *
-* with up to 4 parameters. *
-* *
-* This functions calls the JIT-compiler which eventually translates the *
-* method into machine code. *
-* *
-* An possibly throwed exception will be returned to the caller as function *
-* return value, so the java method cannot return a fucntion value (this *
-* function usually calls 'main' and '<clinit>' which do not return a *
-* function value). *
-* *
-* C-prototype: *
-* javaobject_header *asm_calljavamethod (methodinfo *m, *
-* void *arg1, void *arg2, void *arg3, void *arg4); *
-* *
-*******************************************************************************/
-
-#define MethodPointer -8
-#define FrameSize -12
-#define IsSync -16
-#define IsLeaf -20
-#define IntSave -24
-#define FltSave -28
-#define ExTableSize -32
-#define ExTableStart -32
-
-#define ExEntrySize -32
-#define ExStartPC -8
-#define ExEndPC -16
-#define ExHandlerPC -24
-#define ExCatchType -32
-
- .ent asm_calljavamethod
-
-call_name:
- .ascii "calljavamethod\0\0"
-
- .align 3
- .quad 0 /* catch type all */
- .quad calljava_xhandler /* handler pc */
- .quad calljava_xhandler /* end pc */
- .quad asm_calljavamethod /* start pc */
- .long 1 /* extable size */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 32 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
-
-asm_calljavamethod:
-
- ldgp gp,0(pv)
- lda sp,-32(sp) /* allocate stack space */
- stq gp,24(sp) /* save global pointer */
- stq ra,0(sp) /* save return address */
-
- stq a0,16(sp) /* save method pointer for compiler */
- lda v0,16(sp) /* pass pointer to method pointer via v0*/
-
- mov a1,a0 /* pass the remaining parameters */
- mov a2,a1
- mov a3,a2
- mov a4,a3
-
- lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
- stq $28,8(sp) /* store function address */
- mov sp,$28 /* set method pointer */
-
- ldq pv,8($28) /* method call as in Java */
- jmp ra,(pv) /* call JIT compiler */
-calljava_jit:
- lda pv,-64(ra) /* asm_calljavamethod-calljava_jit !!!!!*/
-
-calljava_return:
-
- ldq ra,0(sp) /* restore return address */
- ldq gp,24(sp) /* restore global pointer */
- lda sp,32(sp) /* free stack space */
- ldl v0,newcompiler /* load newcompiler flag */
- subq v0,1,v0 /* negate for clearing v0 */
- beq v0,calljava_ret /* if newcompiler skip ex copying */
- mov $1,v0 /* pass exception to caller (C) */
-calljava_ret:
- jmp zero,(ra)
-
-calljava_xhandler:
-
- ldq gp,24(sp) /* restore global pointer */
- mov itmp1,a0
- jsr ra,builtin_throw_exception
- ldq ra,0(sp) /* restore return address */
- lda sp,32(sp) /* free stack space */
- jmp zero,(ra)
- .end asm_calljavamethod
-
-
-/********************* function asm_calljavafunction ***************************
-* *
-* This function calls a Java-method (which possibly needs compilation) *
-* with up to 4 address parameters. *
-* *
-* This functions calls the JIT-compiler which eventually translates the *
-* method into machine code. *
-* *
-* C-prototype: *
-* javaobject_header *asm_calljavamethod (methodinfo *m, *
-* void *arg1, void *arg2, void *arg3, void *arg4); *
-* *
-*******************************************************************************/
-
- .ent asm_calljavafunction
-
-call_name2:
- .ascii "calljavafunction\0\0"
-
- .align 3
- .quad 0 /* catch type all */
- .quad calljava_xhandler2 /* handler pc */
- .quad calljava_xhandler2 /* end pc */
- .quad asm_calljavafunction /* start pc */
- .long 1 /* extable size */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 32 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction:
-
- ldgp gp,0(pv)
- lda sp,-32(sp) /* allocate stack space */
- stq gp,24(sp) /* save global pointer */
- stq ra,0(sp) /* save return address */
-
- stq a0,16(sp) /* save method pointer for compiler */
- lda v0,16(sp) /* pass pointer to method pointer via v0*/
-
- mov a1,a0 /* pass the remaining parameters */
- mov a2,a1
- mov a3,a2
- mov a4,a3
-
- lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
- stq $28,8(sp) /* store function address */
- mov sp,$28 /* set method pointer */
-
- ldq pv,8($28) /* method call as in Java */
- jmp ra,(pv) /* call JIT compiler */
-calljava_jit2:
- lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
-
-calljava_return2:
-
- ldq ra,0(sp) /* restore return address */
- ldq gp,24(sp) /* restore global pointer */
- lda sp,32(sp) /* free stack space */
-
-/* ldl v0,newcompiler */ /* load newcompiler flag */
-/* subq v0,1,v0 */ /* negate for clearing v0 */
-/* beq v0,calljava_ret*/ /* if newcompiler skip ex copying */
-/* mov $1,v0 */ /* pass exception to caller (C) */
-calljava_ret2:
- jmp zero,(ra)
-
-calljava_xhandler2:
-
- ldq gp,24(sp) /* restore global pointer */
- mov itmp1,a0
- jsr ra,builtin_throw_exception
- ldq ra,0(sp) /* restore return address */
- lda sp,32(sp) /* free stack space */
- jmp zero,(ra)
- .end asm_calljavafunction
-
-
-/****************** function asm_call_jit_compiler *****************************
-* *
-* invokes the compiler for untranslated JavaVM methods. *
-* *
-* Register R0 contains a pointer to the method info structure (prepared *
-* by createcompilerstub). Using the return address in R26 and the *
-* offset in the LDA instruction or using the value in methodptr R28 the *
-* patching address for storing the method address can be computed: *
-* *
-* method address was either loaded using *
-* M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
-* M_LDA (REG_PV, REG_RA, low) *
-* M_LDAH(REG_PV, REG_RA, high) ; optional *
-* or *
-* M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
-* in the static case the method pointer can be computed using the *
-* return address and the lda function following the jmp instruction *
-* *
-*******************************************************************************/
-
-
- .ent asm_call_jit_compiler
-asm_call_jit_compiler:
-
- ldgp gp,0(pv)
- ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
- srl t8,16,t8 /* shift right register number $yy */
- and t8,31,t8 /* isolate register number */
- subl t8,28,t8 /* test for REG_METHODPTR */
- beq t8,noregchange
- ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t8,48,t8
- sra t8,48,t8 /* isolate offset */
- addq t8,ra,$28 /* compute update address */
- ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
- srl t8,16,t8 /* isolate instruction code */
- lda t8,-0x177b(t8) /* test for LDAH */
- bne t8,noregchange
- ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
- sll t8,16,t8 /* compute high offset */
- addl t8,0,t8 /* sign extend high offset */
- addq t8,$28,$28 /* compute update address */
-noregchange:
- lda sp,-14*8(sp) /* reserve stack space */
- stq a0,0*8(sp) /* save all argument registers */
- stq a1,1*8(sp) /* they could be used by method */
- stq a2,2*8(sp)
- stq a3,3*8(sp)
- stq a4,4*8(sp)
- stq a5,5*8(sp)
- stt $f16,6*8(sp)
- stt $f17,7*8(sp)
- stt $f18,8*8(sp)
- stt $f19,9*8(sp)
- stt $f20,10*8(sp)
- stt $f21,11*8(sp)
- stq $28,12*8(sp) /* save method pointer */
- stq ra,13*8(sp) /* save return address */
-
- ldq a0,0(v0) /* pass 'methodinfo' pointer to */
- jsr ra,jit_compile /* jit compiler */
- ldgp gp,0(ra)
-
- call_pal PAL_imb /* synchronise instruction cache */
-
- ldq a0,0*8(sp) /* load argument registers */
- ldq a1,1*8(sp)
- ldq a2,2*8(sp)
- ldq a3,3*8(sp)
- ldq a4,4*8(sp)
- ldq a5,5*8(sp)
- ldt $f16,6*8(sp)
- ldt $f17,7*8(sp)
- ldt $f18,8*8(sp)
- ldt $f19,9*8(sp)
- ldt $f20,10*8(sp)
- ldt $f21,11*8(sp)
- ldq $28,12*8(sp) /* load method pointer */
- ldq ra,13*8(sp) /* load return address */
- lda sp,14*8(sp) /* deallocate stack area */
-
- ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
- sll t8,48,t8
- sra t8,48,t8 /* isolate offset */
-
- addq t8,$28,t8 /* compute update address via method pointer*/
- stq v0,0(t8) /* save new method address there */
-
- mov v0,pv /* load method address into pv */
-
- jmp zero,(pv) /* and call method. The method returns */
- /* directly to the caller (ra). */
-
- .end asm_call_jit_compiler
-
-
-/****************** function asm_dumpregistersandcall **************************
-* *
-* This funtion saves all callee saved registers and calls the function *
-* which is passed as parameter. *
-* *
-* This function is needed by the garbage collector, which needs to access *
-* all registers which are stored on the stack. Unused registers are *
-* cleared to avoid interferances with the GC. *
-* *
-* void asm_dumpregistersandcall (functionptr f); *
-* *
-*******************************************************************************/
-
- .ent asm_dumpregistersandcall
-asm_dumpregistersandcall:
- lda sp,-16*8(sp) /* allocate stack */
- stq ra,0(sp) /* save return address */
-
- stq s0,1*8(sp) /* save all callee saved registers */
- stq s1,2*8(sp) /* intialize the remaining registers */
- stq s2,3*8(sp)
- stq s3,4*8(sp)
- stq s4,5*8(sp)
- stq s5,6*8(sp)
- stq s6,7*8(sp)
- stt $f2,8*8(sp)
- stt $f3,9*8(sp)
- stt $f4,10*8(sp)
- stt $f5,11*8(sp)
- stt $f6,12*8(sp)
- stt $f7,13*8(sp)
- stt $f8,14*8(sp)
- stt $f9,15*8(sp)
-
- clr v0 /* intialize the remaining registers */
- clr t0
- clr t1
- clr t2
- clr t3
- clr t4
- clr t5
- clr t6
- clr t7
- clr a1
- clr a2
- clr a3
- clr a4
- clr a5
- clr t8
- clr t9
- clr t10
- clr t11
- clr t12
- clr $28
- clr $29
- cpys $f31,$f31,$f0
- cpys $f31,$f31,$f1
- cpys $f31,$f31,$f10
- cpys $f31,$f31,$f11
- cpys $f31,$f31,$f12
- cpys $f31,$f31,$f13
- cpys $f31,$f31,$f14
- cpys $f31,$f31,$f15
- cpys $f31,$f31,$f16
- cpys $f31,$f31,$f17
- cpys $f31,$f31,$f18
- cpys $f31,$f31,$f19
- cpys $f31,$f31,$f20
- cpys $f31,$f31,$f21
- cpys $f31,$f31,$f22
- cpys $f31,$f31,$f23
- cpys $f31,$f31,$f24
- cpys $f31,$f31,$f25
- cpys $f31,$f31,$f26
- cpys $f31,$f31,$f27
- cpys $f31,$f31,$f28
- cpys $f31,$f31,$f29
- cpys $f31,$f31,$f30
-
- mov a0,pv /* load function pointer */
- jmp ra,(pv) /* and call function */
-
- ldq ra,0(sp) /* load return address */
- lda sp,16*8(sp) /* deallocate stack */
- jmp zero,(ra) /* return */
-
- .end asm_dumpregistersandcall
-
-
-/********************* function asm_handle_exception ***************************
-* *
-* This function handles an exception. It does not use the usual calling *
-* conventions. The exception pointer is passed in REG_ITMP1 and the *
-* pc from the exception raising position is passed in REG_ITMP2. It searches *
-* the local exception table for a handler. If no one is found, it unwinds *
-* stacks and continues searching the callers. *
-* *
-* void asm_handle_exception (exceptionptr, exceptionpc); *
-* *
-*******************************************************************************/
-
- .ent asm_handle_nat_exception
-asm_handle_nat_exception:
-
- ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,48,t0
- sra t0,48,t0 /* isolate offset */
- addq t0,ra,pv /* compute update address */
- ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
- srl t0,16,t0 /* isolate instruction code */
- lda t0,-0x177b(t0) /* test for LDAH */
- bne t0,asm_handle_exception
- ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
- sll t0,16,t0 /* compute high offset */
- addl t0,0,t0 /* sign extend high offset */
- addq t0,pv,pv /* compute update address */
-
- .aent asm_handle_exception
-asm_handle_exception:
-
- lda sp,-18*8(sp) /* allocate stack */
- stq t0,0*8(sp) /* save possible used registers */
- stq t1,1*8(sp) /* also registers used by trace_exception */
- stq t2,2*8(sp)
- stq t3,3*8(sp)
- stq t4,4*8(sp)
- stq t5,5*8(sp)
- stq t6,6*8(sp)
- stq t7,7*8(sp)
- stq t8,8*8(sp)
- stq t9,9*8(sp)
- stq t10,10*8(sp)
- stq v0,11*8(sp)
- stq a0,12*8(sp)
- stq a1,13*8(sp)
- stq a2,14*8(sp)
- stq a3,15*8(sp)
- stq a4,16*8(sp)
- stq a5,17*8(sp)
-
- lda t3,1(zero) /* set no unwind flag */
-ex_stack_loop:
- lda sp,-5*8(sp) /* allocate stack */
- stq xptr,0*8(sp) /* save used register */
- stq xpc,1*8(sp)
- stq pv,2*8(sp)
- stq ra,3*8(sp)
- stq t3,4*8(sp)
-
- mov xptr,a0
- ldq a1,MethodPointer(pv)
- mov xpc,a2
- mov t3,a3
- br ra,ex_trace /* set ra for gp loading */
-ex_trace:
- ldgp gp,0(ra) /* load gp */
- jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
-
- ldq xptr,0*8(sp) /* restore used register */
- ldq xpc,1*8(sp)
- ldq pv,2*8(sp)
- ldq ra,3*8(sp)
- ldq t3,4*8(sp)
- lda sp,5*8(sp) /* deallocate stack */
-
- ldl t0,ExTableSize(pv) /* t0 = exception table size */
- beq t0,empty_table /* if empty table skip */
- lda t1,ExTableStart(pv) /* t1 = start of exception table */
-
-ex_table_loop:
- ldq t2,ExStartPC(t1) /* t2 = exception start pc */
- cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
- beq t2,ex_table_cont /* if (false) continue */
- ldq t2,ExEndPC(t1) /* t2 = exception end pc */
- cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
- beq t2,ex_table_cont /* if (false) continue */
- ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
- beq a1,ex_handle_it /* NULL catches everything */
-
- ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
- ldq a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
- ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
- ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
- ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
- subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
- cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
- beq v0,ex_table_cont /* if (false) continue */
-
-ex_handle_it:
-
- ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
-
- beq t3,ex_jump /* if (!(no stack unwinding) skip */
-
- ldq t0,0*8(sp) /* restore possible used registers */
- ldq t1,1*8(sp) /* also registers used by trace_exception */
- ldq t2,2*8(sp)
- ldq t3,3*8(sp)
- ldq t4,4*8(sp)
- ldq t5,5*8(sp)
- ldq t6,6*8(sp)
- ldq t7,7*8(sp)
- ldq t8,8*8(sp)
- ldq t9,9*8(sp)
- ldq t10,10*8(sp)
- ldq v0,11*8(sp)
- ldq a0,12*8(sp)
- ldq a1,13*8(sp)
- ldq a2,14*8(sp)
- ldq a3,15*8(sp)
- ldq a4,16*8(sp)
- ldq a5,17*8(sp)
- lda sp,18*8(sp) /* deallocate stack */
-
-ex_jump:
- jmp zero,(xpc) /* jump to the handler */
-
-ex_table_cont:
- lda t1,ExEntrySize(t1) /* next exception table entry */
- subl t0,1,t0 /* decrement entry counter */
- bgt t0,ex_table_loop /* if (t0 > 0) next entry */
-
-empty_table:
- beq t3,ex_already_cleared /* if here the first time, then */
- lda sp,18*8(sp) /* deallocate stack and */
- clr t3 /* clear the no unwind flag */
-ex_already_cleared:
- ldl t0,IsSync(pv) /* t0 = SyncOffset */
- beq t0,no_monitor_exit /* if zero no monitorexit */
- addq sp,t0,t0 /* add stackptr to Offset */
- ldq a0,-8(t0) /* load monitorexit pointer */
-
- lda sp,-7*8(sp) /* allocate stack */
- stq t0,0*8(sp) /* save used register */
- stq t1,1*8(sp)
- stq t3,2*8(sp)
- stq xptr,3*8(sp)
- stq xpc,4*8(sp)
- stq pv,5*8(sp)
- stq ra,6*8(sp)
-
- br ra,ex_mon_load /* set ra for gp loading */
-ex_mon_load:
- ldgp gp,0(ra) /* load gp */
- jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
-
- ldq t0,0*8(sp) /* restore used register */
- ldq t1,1*8(sp)
- ldq t3,2*8(sp)
- ldq xptr,3*8(sp)
- ldq xpc,4*8(sp)
- ldq pv,5*8(sp)
- ldq ra,6*8(sp)
- lda sp,7*8(sp) /* deallocate stack */
-
-no_monitor_exit:
- ldl t0,FrameSize(pv) /* t0 = frame size */
- addq sp,t0,sp /* unwind stack */
- mov sp,t0 /* t0 = pointer to save area */
- ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
- bne t1,ex_no_restore /* if (leaf) skip */
- ldq ra,-8(t0) /* restore ra */
- lda t0,-8(t0) /* t0-- */
-ex_no_restore:
- mov ra,xpc /* the new xpc is ra */
- ldl t1,IntSave(pv) /* t1 = saved int register count */
- br t2,ex_int1 /* t2 = current pc */
-ex_int1:
- lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
- negl t1,t1 /* negate register count */
- s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
- jmp zero,(t2) /* jump to save position */
- ldq s0,-56(t0)
- ldq s1,-48(t0)
- ldq s2,-40(t0)
- ldq s3,-32(t0)
- ldq s4,-24(t0)
- ldq s5,-16(t0)
- ldq s6,-8(t0)
-ex_int2:
- s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
-
- ldl t1,FltSave(pv) /* t1 = saved flt register count */
- br t2,ex_flt1 /* t2 = current pc */
-ex_flt1:
- lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
- negl t1,t1 /* negate register count */
- s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
- jmp zero,(t2) /* jump to save position */
- ldt $f2,-64(t0)
- ldt $f3,-56(t0)
- ldt $f4,-48(t0)
- ldt $f5,-40(t0)
- ldt $f6,-32(t0)
- ldt $f7,-24(t0)
- ldt $f8,-16(t0)
- ldt $f9,-8(t0)
-ex_flt2:
- ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,48,t0
- sra t0,48,t0 /* isolate offset */
- addq t0,ra,pv /* compute update address */
- ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
- srl t0,16,t0 /* isolate instruction code */
- lda t0,-0x177b(t0) /* test for LDAH */
- bne t0,ex_stack_loop
- ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,16,t0 /* compute high offset */
- addl t0,0,t0 /* sign extend high offset */
- addq t0,pv,pv /* compute update address */
- br ex_stack_loop
-
- .end asm_handle_nat_exception
-
-
-/********************* function asm_builtin_monitorenter ***********************
-* *
-* Does null check and calls monitorenter or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_monitorenter
-asm_builtin_monitorenter:
-
- ldgp gp,0(pv)
- lda pv,builtin_monitorenter
- beq a0,nb_monitorenter /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_monitorenter */
-
-nb_monitorenter:
- ldq xptr,proto_java_lang_NullPointerException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_monitorenter
-
-
-/********************* function asm_builtin_monitorexit ************************
-* *
-* Does null check and calls monitorexit or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_monitorexit
-asm_builtin_monitorexit:
-
- ldgp gp,0(pv)
- lda pv,builtin_monitorexit
- beq a0,nb_monitorexit /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_monitorexit */
-
-nb_monitorexit:
- ldq xptr,proto_java_lang_NullPointerException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_monitorexit
-
-
-/************************ function asm_builtin_idiv ****************************
-* *
-* Does null check and calls idiv or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_idiv
-asm_builtin_idiv:
-
- ldgp gp,0(pv)
- lda pv,builtin_idiv
- beq a1,nb_idiv /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_idiv */
-
-nb_idiv:
- ldq xptr,proto_java_lang_ArithmeticException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_idiv
-
-
-/************************ function asm_builtin_ldiv ****************************
-* *
-* Does null check and calls ldiv or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_ldiv
-asm_builtin_ldiv:
-
- ldgp gp,0(pv)
- lda pv,builtin_ldiv
- beq a1,nb_ldiv /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_ldiv */
-
-nb_ldiv:
- ldq xptr,proto_java_lang_ArithmeticException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_ldiv
-
-
-/************************ function asm_builtin_irem ****************************
-* *
-* Does null check and calls irem or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_irem
-asm_builtin_irem:
-
- ldgp gp,0(pv)
- lda pv,builtin_irem
- beq a1,nb_irem /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_irem */
-
-nb_irem:
- ldq xptr,proto_java_lang_ArithmeticException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_irem
-
-
-/************************ function asm_builtin_lrem ****************************
-* *
-* Does null check and calls lrem or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_lrem
-asm_builtin_lrem:
-
- ldgp gp,0(pv)
- lda pv,builtin_lrem
- beq a1,nb_lrem /* if (null) throw exception */
- jmp zero,(pv) /* else call builtin_lrem */
-
-nb_lrem:
- ldq xptr,proto_java_lang_ArithmeticException
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_lrem
-
-
- /*********************** function new_builtin_checkcast ************************
- * *
- * Does the cast check and eventually throws an exception *
- * *
- *******************************************************************************/
-
- .ent asm_builtin_checkcast
-asm_builtin_checkcast:
-
- ldgp gp,0(pv)
- lda sp,-16(sp) # allocate stack space
- stq ra,0(sp) # save return address
- stq a0,8(sp) # save object pointer
- jsr ra,builtin_checkcast # builtin_checkcast
- ldgp gp,0(ra)
- beq v0,nb_ccast_throw # if (false) throw exception
- ldq ra,0(sp) # restore return address
- ldq v0,8(sp) # return object pointer
- lda sp,16(sp) # free stack space
- jmp zero,(ra)
-
-nb_ccast_throw:
- ldq xptr,proto_java_lang_ClassCastException
- ldq ra,0(sp) # restore return address
- lda sp,16(sp) # free stack space
- lda xpc,-4(ra) # faulting address is return adress - 4
- br asm_handle_nat_exception
- .end asm_builtin_checkcast
-
-
-/******************* function asm_builtin_checkarraycast ***********************
-* *
-* Does the cast check and eventually throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_checkarraycast
-asm_builtin_checkarraycast:
-
- ldgp gp,0(pv)
- lda sp,-16(sp) /* allocate stack space */
- stq ra,0(sp) /* save return address */
- stq a0,8(sp) /* save object pointer */
- jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
- ldgp gp,0(ra)
- beq v0,nb_carray_throw /* if (false) throw exception */
- ldq ra,0(sp) /* restore return address */
- ldq v0,8(sp) /* return object pointer */
- lda sp,16(sp) /* free stack space */
- jmp zero,(ra)
-
-nb_carray_throw:
- ldq xptr,proto_java_lang_ClassCastException
- ldq ra,0(sp) /* restore return address */
- lda sp,16(sp) /* free stack space */
- lda xpc,-4(ra) /* faulting address is return adress - 4*/
- br asm_handle_nat_exception
- .end asm_builtin_checkarraycast
-
-
-/******************* function asm_builtin_aastore ******************************
-* *
-* Does the cast check and eventually throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_aastore
-asm_builtin_aastore:
-
- ldgp gp,0(pv)
- beq a0,nb_aastore_null /* if null pointer throw exception */
- ldl t0,offarraysize(a0) /* load size */
- lda sp,-24(sp) /* allocate stack space */
- stq ra,0(sp) /* save return address */
- s8addq a1,a0,t1 /* add index*8 to arrayref */
- cmpult a1,t0,t0 /* do bound check */
- beq t0,nb_aastore_bound /* if out of bounds throw exception */
- mov a2,a1 /* object is second argument */
- stq t1,8(sp) /* save store position */
- stq a1,16(sp) /* save object */
- jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
- ldgp gp,0(ra)
- ldq ra,0(sp) /* restore return address */
- ldq a0,8(sp) /* restore store position */
- ldq a1,16(sp) /* restore object */
- lda sp,24(sp) /* free stack space */
- beq v0,nb_aastore_throw /* if (false) throw exception */
- stq a1,offobjarrdata(a0) /* store objectptr in array */
- jmp zero,(ra)
-
-nb_aastore_null:
- ldq xptr,proto_java_lang_NullPointerException
- mov ra,xpc /* faulting address is return adress */
- br asm_handle_nat_exception
-
-nb_aastore_bound:
- ldq xptr,proto_java_lang_ArrayIndexOutOfBoundsException
- lda sp,24(sp) /* free stack space */
- mov ra,xpc /* faulting address is return adress */
- br asm_handle_nat_exception
-
-nb_aastore_throw:
- ldq xptr,proto_java_lang_ArrayStoreException
- mov ra,xpc /* faulting address is return adress */
- br asm_handle_nat_exception
-
- .end asm_builtin_aastore
-
-
-/******************* function asm_initialize_thread_stack **********************
-* *
-* initialized a thread stack *
-* *
-*******************************************************************************/
-
- .ent asm_initialize_thread_stack
-asm_initialize_thread_stack:
-
- lda a1,-128(a1)
- stq zero, 0(a1)
- stq zero, 8(a1)
- stq zero, 16(a1)
- stq zero, 24(a1)
- stq zero, 32(a1)
- stq zero, 40(a1)
- stq zero, 48(a1)
- stt fzero, 56(a1)
- stt fzero, 64(a1)
- stt fzero, 72(a1)
- stt fzero, 80(a1)
- stt fzero, 88(a1)
- stt fzero, 96(a1)
- stt fzero, 104(a1)
- stt fzero, 112(a1)
- stq a0, 120(a1)
- mov a1, v0
- jmp zero,(ra)
- .end asm_initialize_thread_stack
-
-
-/******************* function asm_perform_threadswitch *************************
-* *
-* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
-* *
-* performs a threadswitch *
-* *
-*******************************************************************************/
-
- .ent asm_perform_threadswitch
-asm_perform_threadswitch:
-
- subq sp,128,sp
- stq s0, 0(sp)
- stq s1, 8(sp)
- stq s2, 16(sp)
- stq s3, 24(sp)
- stq s4, 32(sp)
- stq s5, 40(sp)
- stq s6, 48(sp)
- stt sf0, 56(sp)
- stt sf1, 64(sp)
- stt sf2, 72(sp)
- stt sf3, 80(sp)
- stt sf4, 88(sp)
- stt sf5, 96(sp)
- stt sf6, 104(sp)
- stt sf7, 112(sp)
- stq ra, 120(sp)
- stq sp, 0(a0)
- stq sp, 0(a2)
- ldq sp, 0(a1)
- ldq s0, 0(sp)
- ldq s1, 8(sp)
- ldq s2, 16(sp)
- ldq s3, 24(sp)
- ldq s4, 32(sp)
- ldq s5, 40(sp)
- ldq s6, 48(sp)
- ldt sf0, 56(sp)
- ldt sf1, 64(sp)
- ldt sf2, 72(sp)
- ldt sf3, 80(sp)
- ldt sf4, 88(sp)
- ldt sf5, 96(sp)
- ldt sf6, 104(sp)
- ldt sf7, 112(sp)
- ldq ra, 120(sp)
- mov ra, pv
- addq sp, 128, sp
- jmp zero,(ra)
- .end asm_perform_threadswitch
-
-
-/********************* function asm_switchstackandcall *************************
-* *
-* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
-* *
-* Switches to a new stack, calls a function and switches back. *
-* a0 new stack pointer *
-* a1 function pointer *
-* a2 pointer to variable where stack top should be stored *
-* *
-*******************************************************************************/
-
-
- .ent asm_switchstackandcall
-asm_switchstackandcall:
- lda a0,-2*8(a0) /* allocate new stack */
- stq ra,0(a0) /* save return address on new stack */
- stq sp,1*8(a0) /* save old stack pointer on new stack */
- stq sp,0(a2) /* save old stack pointer to variable */
- mov a0,sp /* switch to new stack */
-
- mov a1,pv /* load function pointer */
- jmp ra,(pv) /* and call function */
-
- ldq ra,0(sp) /* load return address */
- ldq sp,1*8(sp) /* switch to old stack */
-
- jmp zero,(ra) /* return */
-
- .end asm_switchstackandcall
-
-
-/********************* function asm_getcallingmethod ***************************
-* *
-* classinfo *asm_getcallingmethodclass (); *
-* *
-* goes back stack frames to get the calling method *
-* *
-* t2 .. sp *
-* t3 .. ra *
-* t4 .. pv *
-* *
-*******************************************************************************/
-
-
- .ent asm_getcallingmethod
-asm_getcallingmethod:
-
- ldq t3,16(sp) /* load return address of native function */
- addq sp,24,t2 /* skip frames of C-Function and nativestub */
-
- /* determine pv (t3) of java-function from ra */
-
- ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
- sll t0,48,t0
- sra t0,48,t0 /* isolate offset */
- addq t0,t3,t4 /* compute update address */
- ldl t0,4(t3) /* load instruction LDAH PV,xxx(PV) */
- srl t0,16,t0 /* isolate instruction code */
- lda t0,-0x177b(t0) /* test for LDAH */
- bne t0,pv_ok1
- ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
- sll t0,16,t0 /* compute high offset */
- addl t0,0,t0 /* sign extend high offset */
- addq t0,t4,t4 /* compute update address */
-
-pv_ok1:
- ldl t0,FrameSize(t4) /* t0 = frame size */
- addq t2,t0,t2 /* skip frame of java function */
- ldq t3,-8(t2) /* load new ra */
-
- /* determine pv (t3) of java-function from ra */
-
- ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
- sll t0,48,t0
- sra t0,48,t0 /* isolate offset */
- addq t0,t3,t4 /* compute update address */
- ldl t0,4(t3) /* load instruction LDAH PV,xxx(PV) */
- srl t0,16,t0 /* isolate instruction code */
- lda t0,-0x177b(t0) /* test for LDAH */
- bne t0,pv_ok2
- ldl t0,0(t3) /* load instruction LDA PV,xxx(RA) */
- sll t0,16,t0 /* compute high offset */
- addl t0,0,t0 /* sign extend high offset */
- addq t0,t4,t4 /* compute update address */
-
-pv_ok2:
- ldq v0,MethodPointer(t4) /* */
-
-
- jmp zero,(ra) /* return */
-
- .end asm_getcallingmethod
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- /dev/null
+/* -*- mode: asm; tab-width: 4 -*- */
+/****************************** asmpart.c **************************************
+* *
+* is an assembly language file, but called .c to fake the preprocessor. *
+* It contains the Java-C interface functions for Alpha processors. *
+* *
+* Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst *
+* *
+* See file COPYRIGHT for information on usage and disclaimer of warranties *
+* *
+* Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at *
+* *
+* Last Change: 1998/11/23 *
+* *
+*******************************************************************************/
+
+#include "offsets.h"
+
+#define zero $0
+#define itmp1 $1
+#define v0 $2
+#define itmp2 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+
+#define a4 $8
+#define a5 $9
+#define a6 $10
+#define a7 $11
+#define t0 $12
+#define t1 $13
+#define t2 $14
+#define t3 $15
+
+#define s0 $16
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+
+#define t4 $24
+#define itmp3 $25
+#define k0 $26
+#define k1 $27
+
+#define gp $28
+#define sp $29
+#define s8 $30
+#define ra $31
+
+#define pv s8
+
+#define xptr itmp1
+#define xpc itmp2
+#define mptr itmp3
+#define mptrreg 25
+
+#define fv0 $f0
+#define ft0 $f1
+#define ft1 $f2
+#define ft2 $f3
+#define ft3 $f4
+#define ft4 $f5
+#define ft5 $f6
+#define ft6 $f7
+
+#define ft7 $f8
+#define ft8 $f9
+#define ft9 $f10
+#define ft10 $f11
+#define fa0 $f12
+#define fa1 $f13
+#define fa2 $f14
+#define fa3 $f15
+
+#define fa4 $f16
+#define fa5 $f17
+#define fa6 $f18
+#define fa7 $f19
+#define ft11 $f20
+#define ft12 $f21
+#define ft13 $f22
+#define ft14 $f23
+
+#define fs0 $f24
+#define ft15 $f25
+#define fs1 $f26
+#define ft16 $f27
+#define fs2 $f28
+#define ft17 $f29
+#define fs3 $f30
+#define ft18 $f31
+
+#define fss0 $f20
+#define fss1 $f22
+#define fss2 $f25
+#define fss3 $f27
+#define fss4 $f29
+#define fss5 $f31
+
+#define aaddu daddu
+#define asubu dsubu
+#define aaddiu daddiu
+#define ald ld
+#define ast sd
+#define ala dla
+#define asll dsll
+#define ashift 3
+
+#define MethodPointer -8
+#define FrameSize -12
+#define IsSync -16
+#define IsLeaf -20
+#define IntSave -24
+#define FltSave -28
+#define ExTableSize -32
+#define ExTableStart -32
+
+#define ExEntrySize -32
+#define ExStartPC -8
+#define ExEndPC -16
+#define ExHandlerPC -24
+#define ExCatchType -32
+
+
+ .text
+ .set noat
+
+
+/********************* exported functions and variables ***********************/
+
+ .globl has_no_x_instr_set
+ .globl synchronize_caches
+ .globl asm_calljavamethod
+ .globl asm_call_jit_compiler
+ .globl asm_dumpregistersandcall
+ .globl asm_handle_exception
+ .globl asm_handle_nat_exception
+ .globl asm_builtin_checkarraycast
+ .globl asm_builtin_aastore
+ .globl asm_builtin_monitorenter
+ .globl asm_builtin_monitorexit
+ .globl asm_builtin_idiv
+ .globl asm_builtin_irem
+ .globl asm_builtin_ldiv
+ .globl asm_builtin_lrem
+ .globl asm_perform_threadswitch
+ .globl asm_initialize_thread_stack
+ .globl asm_switchstackandcall
+
+
+/*************************** imported functions *******************************/
+
+ .globl jit_compile
+ .globl builtin_monitorexit
+ .globl builtin_throw_exception
+ .globl builtin_trace_exception
+ .globl class_java_lang_Object
+
+
+/*********************** function has_no_x_instr_set ***************************
+* *
+* determines if the byte support instruction set (21164a and higher) *
+* is available. *
+* *
+*******************************************************************************/
+
+ .ent has_no_x_instr_set
+has_no_x_instr_set:
+
+ move v0,zero /* result code 0 (not used for MIPS) */
+ j ra /* return */
+
+ .end has_no_x_instr_set
+
+
+/********************* function synchronize_caches ****************************/
+
+ .ent synchronize_caches
+synchronize_caches:
+
+/* li a0,BCACHE */ /* flush both caches */
+/* li v0,SYS_cacheflush */ /* Syscall number for cacheflush() */
+/* syscall */ /* call cacheflush() */
+ j ra /* return */
+
+ .end synchronize_caches
+
+
+#if 0
+
+/********************* function asm_calljavamethod *****************************
+* *
+* This function calls a Java-method (which possibly needs compilation) *
+* with up to 4 address parameters. *
+* *
+* This functions calls the JIT-compiler which eventually translates the *
+* method into machine code. *
+* *
+* A possibly throwed exception will be returned to the caller as function *
+* return value, so the java method cannot return a fucntion value (this *
+* function usually calls 'main' and '<clinit>' which do not return a *
+* function value). *
+* *
+* C-prototype: *
+* javaobject_header *asm_calljavamethod (methodinfo *m, *
+* void *arg1, void *arg2, void *arg3, void *arg4); *
+* *
+*******************************************************************************/
+
+ .ent asm_calljavamethod
+
+call_name:
+
+ .ascii "calljavamethod\0\0"
+
+ .align 3
+ .dword 0 /* catch type all */
+ .dword calljava_xhandler /* handler pc */
+ .dword calljava_xhandler /* end pc */
+ .dword asm_calljavamethod /* start pc */
+ .word 1 /* extable size */
+ .word 0 /* fltsave */
+ .word 0 /* intsave */
+ .word 0 /* isleaf */
+ .word 0 /* IsSync */
+ .word 80 /* frame size */
+ .dword 0 /* method pointer (pointer to name) */
+
+asm_calljavamethod:
+
+ aaddiu sp,sp,-10*8 /* allocate stack space */
+ sd ra,0(sp) /* save return address */
+
+ .set noreorder
+ bal call_java_pc
+ sd pv,3*8(sp) /* procedure vector */
+call_java_pc:
+ aaddiu pv,ra,-4*4
+
+ .set reorder
+
+ sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
+ sdc1 fss1,5*8(sp)
+ sdc1 fss2,6*8(sp)
+ sdc1 fss3,7*8(sp)
+ sdc1 fss4,8*8(sp)
+ sdc1 fss5,9*8(sp)
+ sd a0,2*8(sp) /* save method pointer for compiler */
+ aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */
+
+ move a0,a1 /* pass the remaining parameters */
+ move a1,a2
+ move a2,a3
+ move a3,a4
+
+ ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
+ ast mptr,1*8(sp) /* store function address */
+ move mptr,sp /* set method pointer */
+
+ .set noreorder
+
+ ald pv,1*8(mptr) /* method call as in Java */
+ jalr pv /* call JIT compiler */
+ nop
+ aaddiu pv,ra,-23*4 /* recompute procedure vector */
+ move v0,zero /* clear return value (exception ptr) */
+
+ .set reorder
+
+calljava_return:
+
+ ld ra,0(sp) /* restore return address */
+ ld pv,3*8(sp) /* restore procedure vector */
+
+ ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
+ ldc1 fss1,5*8(sp)
+ ldc1 fss2,6*8(sp)
+ ldc1 fss3,7*8(sp)
+ ldc1 fss4,8*8(sp)
+ ldc1 fss5,9*8(sp)
+ aaddiu sp,sp,10*8 /* free stack space */
+ j ra /* return */
+
+calljava_xhandler:
+
+ move a0,itmp1
+ jal builtin_throw_exception
+ b calljava_return
+
+ .end asm_calljavamethod
+
+#endif
+
+
+/****************** function asm_call_jit_compiler *****************************
+* *
+* invokes the compiler for untranslated JavaVM methods. *
+* *
+* Register REG_ITEMP1 contains a pointer to the method info structure *
+* (prepared by createcompilerstub). Using the return address in R31 and the *
+* offset in the LDA instruction or using the value in methodptr R25 the *
+* patching address for storing the method address can be computed: *
+* *
+* method address was either loaded using *
+* M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
+* M_JSR (REG_RA, REG_PV); *
+* M_NOP *
+* M_LDA (REG_PV, REG_RA, val) *
+* or *
+* M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
+* M_JSR (REG_RA, REG_PV); *
+* M_NOP *
+* in the static case the method pointer can be computed using the *
+* return address and the lda function following the jmp instruction *
+* *
+*******************************************************************************/
+
+
+ .ent asm_call_jit_compiler
+asm_call_jit_compiler:
+
+ lw t0,-12(ra) /* load instruction LD PV,xxx($y) */
+ srl t0,t0,21 /* shift right register number $y */
+ and t0,t0,31 /* isolate register number */
+ addiu t0,t0,-mptrreg /* test for REG_METHODPTR */
+ beqz t0,noregchange
+
+ lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,t0,16
+ sra t0,t0,16 /* isolate offset */
+ aaddu mptr,t0,ra /* compute update address */
+
+noregchange:
+
+ aaddiu sp,sp,-18*8 /* allocate stack space */
+ sd a0,0*8(sp) /* save all argument registers */
+ sd a1,1*8(sp) /* they could be used by method */
+ sd a2,2*8(sp)
+ sd a3,3*8(sp)
+ sd a4,4*8(sp)
+ sd a5,5*8(sp)
+ sd a6,6*8(sp)
+ sd a7,7*8(sp)
+ sdc1 fa0,8*8(sp)
+ sdc1 fa1,9*8(sp)
+ sdc1 fa2,10*8(sp)
+ sdc1 fa3,11*8(sp)
+ sdc1 fa4,12*8(sp)
+ sdc1 fa5,13*8(sp)
+ sdc1 fa6,14*8(sp)
+ sdc1 fa7,15*8(sp)
+ sd mptr,16*8(sp) /* save method pointer */
+ sd ra,17*8(sp) /* save return address */
+
+ ald a0,0(itmp1) /* pass 'methodinfo' pointer to */
+ jal jit_compile /* jit compiler */
+
+ ld a0,0*8(sp) /* restore argument registers */
+ ld a1,1*8(sp) /* they could be used by method */
+ ld a2,2*8(sp)
+ ld a3,3*8(sp)
+ ld a4,4*8(sp)
+ ld a5,5*8(sp)
+ ld a6,6*8(sp)
+ ld a7,7*8(sp)
+ ldc1 fa0,8*8(sp)
+ ldc1 fa1,9*8(sp)
+ ldc1 fa2,10*8(sp)
+ ldc1 fa3,11*8(sp)
+ ldc1 fa4,12*8(sp)
+ ldc1 fa5,13*8(sp)
+ ldc1 fa6,14*8(sp)
+ ldc1 fa7,15*8(sp)
+ ld mptr,16*8(sp) /* restore method pointer */
+ ld ra,17*8(sp) /* restore return address */
+ aaddiu sp,sp,18*8 /* deallocate stack area */
+
+ lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */
+ sll t0,t0,16
+ sra t0,t0,16 /* isolate offset */
+
+ aaddu t0,t0,mptr /* compute update address via method pointer*/
+ ast v0,0(t0) /* save new method address there */
+
+ move pv,v0 /* move method address into pv */
+
+ jr pv /* and call method. The method returns */
+ /* directly to the caller (ra). */
+
+ .end asm_call_jit_compiler
+
+
+/****************** function asm_dumpregistersandcall **************************
+* *
+* This funtion saves all callee saved (address) registers and calls the *
+* function which is passed as parameter. *
+* *
+* This function is needed by the garbage collector, which needs to access *
+* all registers which are stored on the stack. Unused registers are *
+* cleared to avoid interferances with the GC. *
+* *
+* void asm_dumpregistersandcall (functionptr f); *
+* *
+*******************************************************************************/
+
+ .ent asm_dumpregistersandcall
+asm_dumpregistersandcall:
+ aaddiu sp,sp,-10*8 /* allocate stack */
+ sd ra,0(sp) /* save return address */
+
+ sd s0,1*8(sp) /* save all callee saved registers */
+ sd s1,2*8(sp)
+ sd s2,3*8(sp)
+ sd s3,4*8(sp)
+ sd s4,5*8(sp)
+ sd s5,6*8(sp)
+ sd s6,7*8(sp)
+ sd s7,8*8(sp)
+ sd s8,9*8(sp)
+
+ move itmp3,a0
+ jalr itmp3 /* and call function */
+
+ ld ra,0(sp) /* restore return address */
+ aaddiu sp,sp,10*8 /* deallocate stack */
+ j ra /* return */
+
+ .end asm_dumpregistersandcall
+
+
+/********************* function asm_handle_exception ***************************
+* *
+* This function handles an exception. It does not use the usual calling *
+* conventions. The exception pointer is passed in REG_ITMP1 and the *
+* pc from the exception raising position is passed in REG_ITMP2. It searches *
+* the local exception table for a handler. If no one is found, it unwinds *
+* stacks and continues searching the callers. *
+* *
+* void asm_handle_exception (exceptionptr, exceptionpc); *
+* *
+*******************************************************************************/
+
+ .ent asm_handle_nat_exception
+asm_handle_nat_exception:
+
+ lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,t0,16
+ sra t0,t0,16 /* isolate offset */
+ aaddu pv,t0,ra /* compute update address */
+
+ .aent asm_handle_exception
+asm_handle_exception:
+
+ aaddiu sp,sp,-14*8 /* allocate stack */
+ sd v0,0*8(sp) /* save possible used registers */
+ sd t0,1*8(sp) /* also registers used by trace_exception */
+ sd t1,2*8(sp)
+ sd t2,3*8(sp)
+ sd t3,4*8(sp)
+ sd t4,5*8(sp)
+ sd a0,6*8(sp)
+ sd a1,7*8(sp)
+ sd a2,8*8(sp)
+ sd a3,9*8(sp)
+ sd a4,10*8(sp)
+ sd a5,11*8(sp)
+ sd a6,12*8(sp)
+ sd a7,13*8(sp)
+
+ addu t3,zero,1 /* set no unwind flag */
+ex_stack_loop:
+ aaddiu sp,sp,-6*8 /* allocate stack */
+ sd xptr,0*8(sp) /* save used registers */
+ sd xpc,1*8(sp)
+ sd pv,2*8(sp)
+ sd ra,3*8(sp)
+ sd t3,4*8(sp)
+
+ move a0,xptr
+ ald a1,MethodPointer(pv)
+ move a2,xpc
+ move a3,t3
+ jal builtin_trace_exception /* trace_exception(xptr,methodptr) */
+
+ ld xptr,0*8(sp) /* restore used register */
+ ld xpc,1*8(sp)
+ ld pv,2*8(sp)
+ ld ra,3*8(sp)
+ ld t3,4*8(sp)
+ aaddiu sp,sp,6*8 /* deallocate stack */
+
+ lw t0,ExTableSize(pv) /* t0 = exception table size */
+ beqz t0,empty_table /* if empty table skip */
+ aaddiu t1,pv,ExTableStart /* t1 = start of exception table */
+
+ex_table_loop:
+ ald t2,ExStartPC(t1) /* t2 = exception start pc */
+ slt t2,xpc,t2 /* t2 = (xpc < startpc) */
+ bnez t2,ex_table_cont /* if (true) continue */
+ ald t2,ExEndPC(t1) /* t2 = exception end pc */
+ slt t2,xpc,t2 /* t2 = (xpc < endpc) */
+ beqz t2,ex_table_cont /* if (false) continue */
+ ald a1,ExCatchType(t1) /* arg1 = exception catch type */
+ beqz a1,ex_handle_it /* NULL catches everything */
+
+ ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
+ ald a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
+ lw a0,offbaseval(a0) /* a0 = baseval(xptr) */
+ lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */
+ lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */
+ subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */
+ sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */
+ bnez v0,ex_table_cont /* if (false) continue */
+
+ex_handle_it:
+
+ ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
+
+ beqz t3,ex_jump /* if (!(no stack unwinding) skip */
+
+ ld v0,0*8(sp) /* restore possible used registers */
+ ld t0,1*8(sp) /* also registers used by trace_exception */
+ ld t1,2*8(sp)
+ ld t2,3*8(sp)
+ ld t3,4*8(sp)
+ ld t4,5*8(sp)
+ ld a0,6*8(sp)
+ ld a1,7*8(sp)
+ ld a2,8*8(sp)
+ ld a3,9*8(sp)
+ ld a4,10*8(sp)
+ ld a5,11*8(sp)
+ ld a6,12*8(sp)
+ ld a7,13*8(sp)
+
+ aaddiu sp,sp,14*8 /* deallocate stack */
+
+ex_jump:
+ jr xpc /* jump to the handler */
+
+ex_table_cont:
+ aaddiu t1,t1,ExEntrySize /* next exception table entry */
+ addiu t0,t0,-1 /* decrement entry counter */
+ bgtz t0,ex_table_loop /* if (t0 > 0) next entry */
+
+empty_table:
+ beqz t3,ex_already_cleared /* if here the first time, then */
+ aaddiu sp,sp,14*8 /* deallocate stack and */
+ move t3,zero /* clear the no unwind flag */
+ex_already_cleared:
+ lw t0,IsSync(pv) /* t0 = SyncOffset */
+ beqz t0,no_monitor_exit /* if zero no monitorexit */
+ aaddu t0,sp,t0 /* add stackptr to Offset */
+ ald a0,-8(t0) /* load monitorexit pointer */
+
+ aaddiu sp,sp,-8*8 /* allocate stack */
+ sd t0,0*8(sp) /* save used register */
+ sd t1,1*8(sp)
+ sd t3,2*8(sp)
+ sd xptr,3*8(sp)
+ sd xpc,4*8(sp)
+ sd pv,5*8(sp)
+ sd ra,6*8(sp)
+
+ jal builtin_monitorexit /* builtin_monitorexit(objectptr) */
+
+ ld t0,0*8(sp) /* restore used register */
+ ld t1,1*8(sp)
+ ld t3,2*8(sp)
+ ld xptr,3*8(sp)
+ ld xpc,4*8(sp)
+ ld pv,5*8(sp)
+ ld ra,6*8(sp)
+ aaddiu sp,sp,8*8 /* deallocate stack */
+
+no_monitor_exit:
+ lw t0,FrameSize(pv) /* t0 = frame size */
+ aaddu sp,sp,t0 /* unwind stack */
+ move t0,sp /* t0 = pointer to save area */
+ lw t1,IsLeaf(pv) /* t1 = is leaf procedure */
+ bnez t1,ex_no_restore /* if (leaf) skip */
+ ld ra,-8(t0) /* restore ra */
+ aaddiu t0,t0,-8 /* t0-- */
+ex_no_restore:
+ move xpc,ra /* the new xpc is ra */
+ lw t1,IntSave(pv) /* t1 = saved int register count */
+ ala t2,ex_int2 /* t2 = current pc */
+ sll t1,t1,2 /* t1 = register count * 4 */
+ asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
+ jr t2 /* jump to save position */
+ ld s0,-8*8(t0)
+ ld s1,-7*8(t0)
+ ld s2,-6*8(t0)
+ ld s3,-5*8(t0)
+ ld s4,-4*8(t0)
+ ld s5,-3*8(t0)
+ ld s6,-2*8(t0)
+ ld s7,-1*8(t0)
+ex_int2:
+ sll t1,t1,1 /* t1 = register count * 4 * 2 */
+ asubu t0,t0,t1 /* t0 = t0 - 8 * register count */
+
+ lw t1,FltSave(pv) /* t1 = saved flt register count */
+ ala t2,ex_flt2 /* t2 = current pc */
+ sll t1,t1,2 /* t1 = register count * 4 */
+ asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
+ jr t2 /* jump to save position */
+ ldc1 fs0,-4*8(t0)
+ ldc1 fs1,-3*8(t0)
+ ldc1 fs2,-2*8(t0)
+ ldc1 fs3,-1*8(t0)
+ex_flt2:
+ lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
+ sll t0,t0,16
+ sra t0,t0,16 /* isolate offset */
+ aaddu pv,t0,ra /* compute update address */
+ b ex_stack_loop
+
+ .end asm_handle_nat_exception
+
+
+/********************* function asm_builtin_monitorenter ***********************
+* *
+* Does null check and calls monitorenter or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_monitorenter
+asm_builtin_monitorenter:
+
+ beqz a0,nb_monitorenter /* if (null) throw exception */
+ ala v0,builtin_monitorenter /* else call builtin_monitorenter */
+ j v0
+
+nb_monitorenter:
+ ald xptr,proto_java_lang_NullPointerException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_monitorenter
+
+
+/********************* function asm_builtin_monitorexit ************************
+* *
+* Does null check and calls monitorexit or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_monitorexit
+asm_builtin_monitorexit:
+
+ beqz a0,nb_monitorexit /* if (null) throw exception */
+ ala v0,builtin_monitorexit /* else call builtin_monitorexit */
+ j v0
+
+nb_monitorexit:
+ ald xptr,proto_java_lang_NullPointerException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_monitorexit
+
+
+/************************ function asm_builtin_idiv ****************************
+* *
+* Does null check and calls idiv or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_idiv
+asm_builtin_idiv:
+
+ beqz a1,nb_idiv /* if (null) throw exception */
+ ala v0,builtin_idiv /* else call builtin_idiv */
+ j v0
+
+nb_idiv:
+ ald xptr,proto_java_lang_ArithmeticException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_idiv
+
+
+/************************ function asm_builtin_ldiv ****************************
+* *
+* Does null check and calls ldiv or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_ldiv
+asm_builtin_ldiv:
+
+ beqz a1,nb_ldiv /* if (null) throw exception */
+ ala v0,builtin_ldiv /* else call builtin_ldiv */
+ j v0
+
+nb_ldiv:
+ ald xptr,proto_java_lang_ArithmeticException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_ldiv
+
+
+/************************ function asm_builtin_irem ****************************
+* *
+* Does null check and calls irem or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_irem
+asm_builtin_irem:
+
+ beqz a1,nb_irem /* if (null) throw exception */
+ ala v0,builtin_irem /* else call builtin_irem */
+ j v0
+
+nb_irem:
+ ald xptr,proto_java_lang_ArithmeticException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_irem
+
+
+/************************ function asm_builtin_lrem ****************************
+* *
+* Does null check and calls lrem or throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_lrem
+asm_builtin_lrem:
+
+ beqz a1,nb_lrem /* if (null) throw exception */
+ ala v0,builtin_lrem /* else call builtin_lrem */
+ j v0
+
+nb_lrem:
+ ald xptr,proto_java_lang_ArithmeticException
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_lrem
+
+
+/******************* function asm_builtin_checkarraycast ***********************
+* *
+* Does the cast check and eventually throws an exception *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_checkarraycast
+asm_builtin_checkarraycast:
+
+ aaddiu sp,sp,-16 /* allocate stack space */
+ sd ra,0(sp) /* save return address */
+ sd a0,8(sp) /* save object pointer */
+ jal builtin_checkarraycast /* builtin_checkarraycast */
+ beqz v0,nb_carray_throw /* if (false) throw exception */
+ ld ra,0(sp) /* restore return address */
+ ld v0,8(sp) /* return object pointer */
+ aaddiu sp,sp,16 /* deallocate stack */
+ j ra /* return */
+
+nb_carray_throw:
+ ald xptr,proto_java_lang_ClassCastException
+ ld ra,0(sp) /* restore return address */
+ aaddiu sp,sp,16 /* free stack space */
+ aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
+ b asm_handle_nat_exception
+ .end asm_builtin_checkarraycast
+
+
+/******************* function asm_builtin_aastore ******************************
+* *
+* Does the cast check and eventually throws an exception *
+* a0 = arrayref, a1 = index, a2 = value *
+* *
+*******************************************************************************/
+
+ .ent asm_builtin_aastore
+asm_builtin_aastore:
+
+ beqz a0,nb_aastore_null /* if null pointer throw exception */
+ lw t0,offarraysize(a0) /* load size */
+ aaddiu sp,sp,-32 /* allocate stack space */
+ sd ra,0(sp) /* save return address */
+ asll t1,a1,ashift /* add index*8 to arrayref */
+ aaddu t1,a0,t1 /* add index * ashift to arrayref */
+ sltu t0,a1,t0 /* do bound check */
+ beqz t0,nb_aastore_bound /* if out of bounds throw exception */
+ move a1,a2 /* object is second argument */
+ sd t1,8(sp) /* save store position */
+ sd a1,16(sp) /* save object */
+ jal builtin_canstore /* builtin_canstore(arrayref,object) */
+ ld ra,0(sp) /* restore return address */
+ ld a0,8(sp) /* restore store position */
+ ld a1,16(sp) /* restore object */
+ aaddiu sp,sp,32 /* free stack space */
+ beqz v0,nb_aastore_throw /* if (false) throw exception */
+ ast a1,offobjarrdata(a0) /* store objectptr in array */
+ j ra /* return */
+
+nb_aastore_null:
+ ald xptr,proto_java_lang_NullPointerException
+ move xpc,ra /* faulting address is return adress */
+ b asm_handle_nat_exception
+
+nb_aastore_bound:
+ ald xptr,proto_java_lang_ArrayIndexOutOfBoundsException
+ aaddiu sp,sp,32 /* free stack space */
+ move xpc,ra /* faulting address is return adress */
+ b asm_handle_nat_exception
+
+nb_aastore_throw:
+ ald xptr,proto_java_lang_ArrayStoreException
+ move xpc,ra /* faulting address is return adress */
+ b asm_handle_nat_exception
+
+ .end asm_builtin_aastore
+
+
+/******************* function asm_initialize_thread_stack **********************
+* *
+* u1* asm_initialize_thread_stack (void *func, u1 *stack); *
+* *
+* initialize a thread stack *
+* *
+*******************************************************************************/
+
+ .ent asm_initialize_thread_stack
+asm_initialize_thread_stack:
+
+ aaddiu a1,a1,-14*8 /* allocate save area */
+ sd zero, 0*8(a1) /* s0 initalize thread area */
+ sd zero, 1*8(a1) /* s1 */
+ sd zero, 2*8(a1) /* s2 */
+ sd zero, 3*8(a1) /* s3 */
+ sd zero, 4*8(a1) /* s4 */
+ sd zero, 5*8(a1) /* s5 */
+ sd zero, 6*8(a1) /* s6 */
+ sd zero, 7*8(a1) /* s7 */
+ sd zero, 8*8(a1) /* s8 */
+ sd zero, 9*8(a1) /* fs0 */
+ sd zero,10*8(a1) /* fs1 */
+ sd zero,11*8(a1) /* fs2 */
+ sd zero,12*8(a1) /* fs3 */
+ sd a0, 13*8(a1)
+ move v0,a1
+ j ra /* return */
+ .end asm_initialize_thread_stack
+
+
+/******************* function asm_perform_threadswitch *************************
+* *
+* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
+* *
+* performs a threadswitch *
+* *
+*******************************************************************************/
+
+ .ent asm_perform_threadswitch
+asm_perform_threadswitch:
+
+ aaddiu sp,sp,-14*8 /* allocate new stack */
+ sd s0, 0*8(sp) /* save saved registers of old thread */
+ sd s1, 1*8(sp)
+ sd s2, 2*8(sp)
+ sd s3, 3*8(sp)
+ sd s4, 4*8(sp)
+ sd s5, 5*8(sp)
+ sd s6, 6*8(sp)
+ sd s7, 7*8(sp)
+/* sd s8, 8*8(sp) */
+ sdc1 fs0, 9*8(sp)
+ sdc1 fs1,10*8(sp)
+ sdc1 fs2,11*8(sp)
+ sdc1 fs3,12*8(sp)
+ sd ra, 13*8(sp)
+ ast sp,0(a0) /* save old stack pointer */
+ ast sp,0(a2) /* stackTop = old stack pointer */
+ ald sp,0(a1) /* load new stack pointer */
+ ld s0, 0*8(sp) /* load saved registers of new thread */
+ ld s1, 1*8(sp)
+ ld s2, 2*8(sp)
+ ld s3, 3*8(sp)
+ ld s4, 4*8(sp)
+ ld s5, 5*8(sp)
+ ld s6, 6*8(sp)
+ ld s7, 7*8(sp)
+/* ld s8, 8*8(sp) */
+ ldc1 fs0, 9*8(sp)
+ ldc1 fs1,10*8(sp)
+ ldc1 fs2,11*8(sp)
+ ldc1 fs3,12*8(sp)
+ ld ra, 13*8(sp)
+ aaddiu sp,sp,14*8 /* deallocate new stack */
+ j ra /* return */
+ .end asm_perform_threadswitch
+
+
+/********************* function asm_switchstackandcall *************************
+* *
+* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
+* *
+* Switches to a new stack, calls a function and switches back. *
+* a0 new stack pointer *
+* a1 function pointer *
+* a2 pointer to variable where stack top should be stored *
+* *
+*******************************************************************************/
+
+
+ .ent asm_switchstackandcall
+asm_switchstackandcall:
+ aaddiu a0,a0,-16 /* allocate new stack */
+ sd ra,0(a0) /* save return address on new stack */
+ sd sp,8(a0) /* save old stack pointer on new stack */
+ sd sp,0(a2) /* save old stack pointer to variable */
+ move sp,a0 /* switch to new stack */
+
+ move itmp3,a1
+ jalr itmp3 /* and call function */
+
+ ld ra,0(sp) /* load return address */
+ ld sp,8(sp) /* switch to old stack */
+
+ j ra /* return */
+
+ .end asm_switchstackandcall
+++ /dev/null
-/* -*- mode: asm; tab-width: 4 -*- */
-/****************************** asmpart.c **************************************
-* *
-* is an assembly language file, but called .c to fake the preprocessor. *
-* It contains the Java-C interface functions for Alpha processors. *
-* *
-* Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst *
-* *
-* See file COPYRIGHT for information on usage and disclaimer of warranties *
-* *
-* Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at *
-* *
-* Last Change: 1998/11/23 *
-* *
-*******************************************************************************/
-
-#include "offsets.h"
-
-#define zero $0
-#define itmp1 $1
-#define v0 $2
-#define itmp2 $3
-#define a0 $4
-#define a1 $5
-#define a2 $6
-#define a3 $7
-
-#define a4 $8
-#define a5 $9
-#define a6 $10
-#define a7 $11
-#define t0 $12
-#define t1 $13
-#define t2 $14
-#define t3 $15
-
-#define s0 $16
-#define s1 $17
-#define s2 $18
-#define s3 $19
-#define s4 $20
-#define s5 $21
-#define s6 $22
-#define s7 $23
-
-#define t4 $24
-#define itmp3 $25
-#define k0 $26
-#define k1 $27
-
-#define gp $28
-#define sp $29
-#define s8 $30
-#define ra $31
-
-#define pv s8
-
-#define xptr itmp1
-#define xpc itmp2
-#define mptr itmp3
-#define mptrreg 25
-
-#define fv0 $f0
-#define ft0 $f1
-#define ft1 $f2
-#define ft2 $f3
-#define ft3 $f4
-#define ft4 $f5
-#define ft5 $f6
-#define ft6 $f7
-
-#define ft7 $f8
-#define ft8 $f9
-#define ft9 $f10
-#define ft10 $f11
-#define fa0 $f12
-#define fa1 $f13
-#define fa2 $f14
-#define fa3 $f15
-
-#define fa4 $f16
-#define fa5 $f17
-#define fa6 $f18
-#define fa7 $f19
-#define ft11 $f20
-#define ft12 $f21
-#define ft13 $f22
-#define ft14 $f23
-
-#define fs0 $f24
-#define ft15 $f25
-#define fs1 $f26
-#define ft16 $f27
-#define fs2 $f28
-#define ft17 $f29
-#define fs3 $f30
-#define ft18 $f31
-
-#define fss0 $f20
-#define fss1 $f22
-#define fss2 $f25
-#define fss3 $f27
-#define fss4 $f29
-#define fss5 $f31
-
-#define aaddu daddu
-#define asubu dsubu
-#define aaddiu daddiu
-#define ald ld
-#define ast sd
-#define ala dla
-#define asll dsll
-#define ashift 3
-
-#define MethodPointer -8
-#define FrameSize -12
-#define IsSync -16
-#define IsLeaf -20
-#define IntSave -24
-#define FltSave -28
-#define ExTableSize -32
-#define ExTableStart -32
-
-#define ExEntrySize -32
-#define ExStartPC -8
-#define ExEndPC -16
-#define ExHandlerPC -24
-#define ExCatchType -32
-
-
- .text
- .set noat
-
-
-/********************* exported functions and variables ***********************/
-
- .globl has_no_x_instr_set
- .globl synchronize_caches
- .globl asm_calljavamethod
- .globl asm_call_jit_compiler
- .globl asm_dumpregistersandcall
- .globl asm_handle_exception
- .globl asm_handle_nat_exception
- .globl asm_builtin_checkarraycast
- .globl asm_builtin_aastore
- .globl asm_builtin_monitorenter
- .globl asm_builtin_monitorexit
- .globl asm_builtin_idiv
- .globl asm_builtin_irem
- .globl asm_builtin_ldiv
- .globl asm_builtin_lrem
- .globl asm_perform_threadswitch
- .globl asm_initialize_thread_stack
- .globl asm_switchstackandcall
-
-
-/*************************** imported functions *******************************/
-
- .globl jit_compile
- .globl builtin_monitorexit
- .globl builtin_throw_exception
- .globl builtin_trace_exception
- .globl class_java_lang_Object
-
-
-/*********************** function has_no_x_instr_set ***************************
-* *
-* determines if the byte support instruction set (21164a and higher) *
-* is available. *
-* *
-*******************************************************************************/
-
- .ent has_no_x_instr_set
-has_no_x_instr_set:
-
- move v0,zero /* result code 0 (not used for MIPS) */
- j ra /* return */
-
- .end has_no_x_instr_set
-
-
-/********************* function synchronize_caches ****************************/
-
- .ent synchronize_caches
-synchronize_caches:
-
-/* li a0,BCACHE */ /* flush both caches */
-/* li v0,SYS_cacheflush */ /* Syscall number for cacheflush() */
-/* syscall */ /* call cacheflush() */
- j ra /* return */
-
- .end synchronize_caches
-
-
-#if 0
-
-/********************* function asm_calljavamethod *****************************
-* *
-* This function calls a Java-method (which possibly needs compilation) *
-* with up to 4 address parameters. *
-* *
-* This functions calls the JIT-compiler which eventually translates the *
-* method into machine code. *
-* *
-* A possibly throwed exception will be returned to the caller as function *
-* return value, so the java method cannot return a fucntion value (this *
-* function usually calls 'main' and '<clinit>' which do not return a *
-* function value). *
-* *
-* C-prototype: *
-* javaobject_header *asm_calljavamethod (methodinfo *m, *
-* void *arg1, void *arg2, void *arg3, void *arg4); *
-* *
-*******************************************************************************/
-
- .ent asm_calljavamethod
-
-call_name:
-
- .ascii "calljavamethod\0\0"
-
- .align 3
- .dword 0 /* catch type all */
- .dword calljava_xhandler /* handler pc */
- .dword calljava_xhandler /* end pc */
- .dword asm_calljavamethod /* start pc */
- .word 1 /* extable size */
- .word 0 /* fltsave */
- .word 0 /* intsave */
- .word 0 /* isleaf */
- .word 0 /* IsSync */
- .word 80 /* frame size */
- .dword 0 /* method pointer (pointer to name) */
-
-asm_calljavamethod:
-
- aaddiu sp,sp,-10*8 /* allocate stack space */
- sd ra,0(sp) /* save return address */
-
- .set noreorder
- bal call_java_pc
- sd pv,3*8(sp) /* procedure vector */
-call_java_pc:
- aaddiu pv,ra,-4*4
-
- .set reorder
-
- sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
- sdc1 fss1,5*8(sp)
- sdc1 fss2,6*8(sp)
- sdc1 fss3,7*8(sp)
- sdc1 fss4,8*8(sp)
- sdc1 fss5,9*8(sp)
- sd a0,2*8(sp) /* save method pointer for compiler */
- aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */
-
- move a0,a1 /* pass the remaining parameters */
- move a1,a2
- move a2,a3
- move a3,a4
-
- ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
- ast mptr,1*8(sp) /* store function address */
- move mptr,sp /* set method pointer */
-
- .set noreorder
-
- ald pv,1*8(mptr) /* method call as in Java */
- jalr pv /* call JIT compiler */
- nop
- aaddiu pv,ra,-23*4 /* recompute procedure vector */
- move v0,zero /* clear return value (exception ptr) */
-
- .set reorder
-
-calljava_return:
-
- ld ra,0(sp) /* restore return address */
- ld pv,3*8(sp) /* restore procedure vector */
-
- ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
- ldc1 fss1,5*8(sp)
- ldc1 fss2,6*8(sp)
- ldc1 fss3,7*8(sp)
- ldc1 fss4,8*8(sp)
- ldc1 fss5,9*8(sp)
- aaddiu sp,sp,10*8 /* free stack space */
- j ra /* return */
-
-calljava_xhandler:
-
- move a0,itmp1
- jal builtin_throw_exception
- b calljava_return
-
- .end asm_calljavamethod
-
-#endif
-
-
-/****************** function asm_call_jit_compiler *****************************
-* *
-* invokes the compiler for untranslated JavaVM methods. *
-* *
-* Register REG_ITEMP1 contains a pointer to the method info structure *
-* (prepared by createcompilerstub). Using the return address in R31 and the *
-* offset in the LDA instruction or using the value in methodptr R25 the *
-* patching address for storing the method address can be computed: *
-* *
-* method address was either loaded using *
-* M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
-* M_JSR (REG_RA, REG_PV); *
-* M_NOP *
-* M_LDA (REG_PV, REG_RA, val) *
-* or *
-* M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
-* M_JSR (REG_RA, REG_PV); *
-* M_NOP *
-* in the static case the method pointer can be computed using the *
-* return address and the lda function following the jmp instruction *
-* *
-*******************************************************************************/
-
-
- .ent asm_call_jit_compiler
-asm_call_jit_compiler:
-
- lw t0,-12(ra) /* load instruction LD PV,xxx($y) */
- srl t0,t0,21 /* shift right register number $y */
- and t0,t0,31 /* isolate register number */
- addiu t0,t0,-mptrreg /* test for REG_METHODPTR */
- beqz t0,noregchange
-
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu mptr,t0,ra /* compute update address */
-
-noregchange:
-
- aaddiu sp,sp,-18*8 /* allocate stack space */
- sd a0,0*8(sp) /* save all argument registers */
- sd a1,1*8(sp) /* they could be used by method */
- sd a2,2*8(sp)
- sd a3,3*8(sp)
- sd a4,4*8(sp)
- sd a5,5*8(sp)
- sd a6,6*8(sp)
- sd a7,7*8(sp)
- sdc1 fa0,8*8(sp)
- sdc1 fa1,9*8(sp)
- sdc1 fa2,10*8(sp)
- sdc1 fa3,11*8(sp)
- sdc1 fa4,12*8(sp)
- sdc1 fa5,13*8(sp)
- sdc1 fa6,14*8(sp)
- sdc1 fa7,15*8(sp)
- sd mptr,16*8(sp) /* save method pointer */
- sd ra,17*8(sp) /* save return address */
-
- ald a0,0(itmp1) /* pass 'methodinfo' pointer to */
- jal jit_compile /* jit compiler */
-
- ld a0,0*8(sp) /* restore argument registers */
- ld a1,1*8(sp) /* they could be used by method */
- ld a2,2*8(sp)
- ld a3,3*8(sp)
- ld a4,4*8(sp)
- ld a5,5*8(sp)
- ld a6,6*8(sp)
- ld a7,7*8(sp)
- ldc1 fa0,8*8(sp)
- ldc1 fa1,9*8(sp)
- ldc1 fa2,10*8(sp)
- ldc1 fa3,11*8(sp)
- ldc1 fa4,12*8(sp)
- ldc1 fa5,13*8(sp)
- ldc1 fa6,14*8(sp)
- ldc1 fa7,15*8(sp)
- ld mptr,16*8(sp) /* restore method pointer */
- ld ra,17*8(sp) /* restore return address */
- aaddiu sp,sp,18*8 /* deallocate stack area */
-
- lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
-
- aaddu t0,t0,mptr /* compute update address via method pointer*/
- ast v0,0(t0) /* save new method address there */
-
- move pv,v0 /* move method address into pv */
-
- jr pv /* and call method. The method returns */
- /* directly to the caller (ra). */
-
- .end asm_call_jit_compiler
-
-
-/****************** function asm_dumpregistersandcall **************************
-* *
-* This funtion saves all callee saved (address) registers and calls the *
-* function which is passed as parameter. *
-* *
-* This function is needed by the garbage collector, which needs to access *
-* all registers which are stored on the stack. Unused registers are *
-* cleared to avoid interferances with the GC. *
-* *
-* void asm_dumpregistersandcall (functionptr f); *
-* *
-*******************************************************************************/
-
- .ent asm_dumpregistersandcall
-asm_dumpregistersandcall:
- aaddiu sp,sp,-10*8 /* allocate stack */
- sd ra,0(sp) /* save return address */
-
- sd s0,1*8(sp) /* save all callee saved registers */
- sd s1,2*8(sp)
- sd s2,3*8(sp)
- sd s3,4*8(sp)
- sd s4,5*8(sp)
- sd s5,6*8(sp)
- sd s6,7*8(sp)
- sd s7,8*8(sp)
- sd s8,9*8(sp)
-
- move itmp3,a0
- jalr itmp3 /* and call function */
-
- ld ra,0(sp) /* restore return address */
- aaddiu sp,sp,10*8 /* deallocate stack */
- j ra /* return */
-
- .end asm_dumpregistersandcall
-
-
-/********************* function asm_handle_exception ***************************
-* *
-* This function handles an exception. It does not use the usual calling *
-* conventions. The exception pointer is passed in REG_ITMP1 and the *
-* pc from the exception raising position is passed in REG_ITMP2. It searches *
-* the local exception table for a handler. If no one is found, it unwinds *
-* stacks and continues searching the callers. *
-* *
-* void asm_handle_exception (exceptionptr, exceptionpc); *
-* *
-*******************************************************************************/
-
- .ent asm_handle_nat_exception
-asm_handle_nat_exception:
-
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu pv,t0,ra /* compute update address */
-
- .aent asm_handle_exception
-asm_handle_exception:
-
- aaddiu sp,sp,-14*8 /* allocate stack */
- sd v0,0*8(sp) /* save possible used registers */
- sd t0,1*8(sp) /* also registers used by trace_exception */
- sd t1,2*8(sp)
- sd t2,3*8(sp)
- sd t3,4*8(sp)
- sd t4,5*8(sp)
- sd a0,6*8(sp)
- sd a1,7*8(sp)
- sd a2,8*8(sp)
- sd a3,9*8(sp)
- sd a4,10*8(sp)
- sd a5,11*8(sp)
- sd a6,12*8(sp)
- sd a7,13*8(sp)
-
- addu t3,zero,1 /* set no unwind flag */
-ex_stack_loop:
- aaddiu sp,sp,-6*8 /* allocate stack */
- sd xptr,0*8(sp) /* save used registers */
- sd xpc,1*8(sp)
- sd pv,2*8(sp)
- sd ra,3*8(sp)
- sd t3,4*8(sp)
-
- move a0,xptr
- ald a1,MethodPointer(pv)
- move a2,xpc
- move a3,t3
- jal builtin_trace_exception /* trace_exception(xptr,methodptr) */
-
- ld xptr,0*8(sp) /* restore used register */
- ld xpc,1*8(sp)
- ld pv,2*8(sp)
- ld ra,3*8(sp)
- ld t3,4*8(sp)
- aaddiu sp,sp,6*8 /* deallocate stack */
-
- lw t0,ExTableSize(pv) /* t0 = exception table size */
- beqz t0,empty_table /* if empty table skip */
- aaddiu t1,pv,ExTableStart /* t1 = start of exception table */
-
-ex_table_loop:
- ald t2,ExStartPC(t1) /* t2 = exception start pc */
- slt t2,xpc,t2 /* t2 = (xpc < startpc) */
- bnez t2,ex_table_cont /* if (true) continue */
- ald t2,ExEndPC(t1) /* t2 = exception end pc */
- slt t2,xpc,t2 /* t2 = (xpc < endpc) */
- beqz t2,ex_table_cont /* if (false) continue */
- ald a1,ExCatchType(t1) /* arg1 = exception catch type */
- beqz a1,ex_handle_it /* NULL catches everything */
-
- ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
- ald a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
- lw a0,offbaseval(a0) /* a0 = baseval(xptr) */
- lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */
- lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */
- subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */
- sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */
- bnez v0,ex_table_cont /* if (false) continue */
-
-ex_handle_it:
-
- ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
-
- beqz t3,ex_jump /* if (!(no stack unwinding) skip */
-
- ld v0,0*8(sp) /* restore possible used registers */
- ld t0,1*8(sp) /* also registers used by trace_exception */
- ld t1,2*8(sp)
- ld t2,3*8(sp)
- ld t3,4*8(sp)
- ld t4,5*8(sp)
- ld a0,6*8(sp)
- ld a1,7*8(sp)
- ld a2,8*8(sp)
- ld a3,9*8(sp)
- ld a4,10*8(sp)
- ld a5,11*8(sp)
- ld a6,12*8(sp)
- ld a7,13*8(sp)
-
- aaddiu sp,sp,14*8 /* deallocate stack */
-
-ex_jump:
- jr xpc /* jump to the handler */
-
-ex_table_cont:
- aaddiu t1,t1,ExEntrySize /* next exception table entry */
- addiu t0,t0,-1 /* decrement entry counter */
- bgtz t0,ex_table_loop /* if (t0 > 0) next entry */
-
-empty_table:
- beqz t3,ex_already_cleared /* if here the first time, then */
- aaddiu sp,sp,14*8 /* deallocate stack and */
- move t3,zero /* clear the no unwind flag */
-ex_already_cleared:
- lw t0,IsSync(pv) /* t0 = SyncOffset */
- beqz t0,no_monitor_exit /* if zero no monitorexit */
- aaddu t0,sp,t0 /* add stackptr to Offset */
- ald a0,-8(t0) /* load monitorexit pointer */
-
- aaddiu sp,sp,-8*8 /* allocate stack */
- sd t0,0*8(sp) /* save used register */
- sd t1,1*8(sp)
- sd t3,2*8(sp)
- sd xptr,3*8(sp)
- sd xpc,4*8(sp)
- sd pv,5*8(sp)
- sd ra,6*8(sp)
-
- jal builtin_monitorexit /* builtin_monitorexit(objectptr) */
-
- ld t0,0*8(sp) /* restore used register */
- ld t1,1*8(sp)
- ld t3,2*8(sp)
- ld xptr,3*8(sp)
- ld xpc,4*8(sp)
- ld pv,5*8(sp)
- ld ra,6*8(sp)
- aaddiu sp,sp,8*8 /* deallocate stack */
-
-no_monitor_exit:
- lw t0,FrameSize(pv) /* t0 = frame size */
- aaddu sp,sp,t0 /* unwind stack */
- move t0,sp /* t0 = pointer to save area */
- lw t1,IsLeaf(pv) /* t1 = is leaf procedure */
- bnez t1,ex_no_restore /* if (leaf) skip */
- ld ra,-8(t0) /* restore ra */
- aaddiu t0,t0,-8 /* t0-- */
-ex_no_restore:
- move xpc,ra /* the new xpc is ra */
- lw t1,IntSave(pv) /* t1 = saved int register count */
- ala t2,ex_int2 /* t2 = current pc */
- sll t1,t1,2 /* t1 = register count * 4 */
- asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
- jr t2 /* jump to save position */
- ld s0,-8*8(t0)
- ld s1,-7*8(t0)
- ld s2,-6*8(t0)
- ld s3,-5*8(t0)
- ld s4,-4*8(t0)
- ld s5,-3*8(t0)
- ld s6,-2*8(t0)
- ld s7,-1*8(t0)
-ex_int2:
- sll t1,t1,1 /* t1 = register count * 4 * 2 */
- asubu t0,t0,t1 /* t0 = t0 - 8 * register count */
-
- lw t1,FltSave(pv) /* t1 = saved flt register count */
- ala t2,ex_flt2 /* t2 = current pc */
- sll t1,t1,2 /* t1 = register count * 4 */
- asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
- jr t2 /* jump to save position */
- ldc1 fs0,-4*8(t0)
- ldc1 fs1,-3*8(t0)
- ldc1 fs2,-2*8(t0)
- ldc1 fs3,-1*8(t0)
-ex_flt2:
- lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
- sll t0,t0,16
- sra t0,t0,16 /* isolate offset */
- aaddu pv,t0,ra /* compute update address */
- b ex_stack_loop
-
- .end asm_handle_nat_exception
-
-
-/********************* function asm_builtin_monitorenter ***********************
-* *
-* Does null check and calls monitorenter or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_monitorenter
-asm_builtin_monitorenter:
-
- beqz a0,nb_monitorenter /* if (null) throw exception */
- ala v0,builtin_monitorenter /* else call builtin_monitorenter */
- j v0
-
-nb_monitorenter:
- ald xptr,proto_java_lang_NullPointerException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_monitorenter
-
-
-/********************* function asm_builtin_monitorexit ************************
-* *
-* Does null check and calls monitorexit or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_monitorexit
-asm_builtin_monitorexit:
-
- beqz a0,nb_monitorexit /* if (null) throw exception */
- ala v0,builtin_monitorexit /* else call builtin_monitorexit */
- j v0
-
-nb_monitorexit:
- ald xptr,proto_java_lang_NullPointerException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_monitorexit
-
-
-/************************ function asm_builtin_idiv ****************************
-* *
-* Does null check and calls idiv or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_idiv
-asm_builtin_idiv:
-
- beqz a1,nb_idiv /* if (null) throw exception */
- ala v0,builtin_idiv /* else call builtin_idiv */
- j v0
-
-nb_idiv:
- ald xptr,proto_java_lang_ArithmeticException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_idiv
-
-
-/************************ function asm_builtin_ldiv ****************************
-* *
-* Does null check and calls ldiv or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_ldiv
-asm_builtin_ldiv:
-
- beqz a1,nb_ldiv /* if (null) throw exception */
- ala v0,builtin_ldiv /* else call builtin_ldiv */
- j v0
-
-nb_ldiv:
- ald xptr,proto_java_lang_ArithmeticException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_ldiv
-
-
-/************************ function asm_builtin_irem ****************************
-* *
-* Does null check and calls irem or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_irem
-asm_builtin_irem:
-
- beqz a1,nb_irem /* if (null) throw exception */
- ala v0,builtin_irem /* else call builtin_irem */
- j v0
-
-nb_irem:
- ald xptr,proto_java_lang_ArithmeticException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_irem
-
-
-/************************ function asm_builtin_lrem ****************************
-* *
-* Does null check and calls lrem or throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_lrem
-asm_builtin_lrem:
-
- beqz a1,nb_lrem /* if (null) throw exception */
- ala v0,builtin_lrem /* else call builtin_lrem */
- j v0
-
-nb_lrem:
- ald xptr,proto_java_lang_ArithmeticException
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_lrem
-
-
-/******************* function asm_builtin_checkarraycast ***********************
-* *
-* Does the cast check and eventually throws an exception *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_checkarraycast
-asm_builtin_checkarraycast:
-
- aaddiu sp,sp,-16 /* allocate stack space */
- sd ra,0(sp) /* save return address */
- sd a0,8(sp) /* save object pointer */
- jal builtin_checkarraycast /* builtin_checkarraycast */
- beqz v0,nb_carray_throw /* if (false) throw exception */
- ld ra,0(sp) /* restore return address */
- ld v0,8(sp) /* return object pointer */
- aaddiu sp,sp,16 /* deallocate stack */
- j ra /* return */
-
-nb_carray_throw:
- ald xptr,proto_java_lang_ClassCastException
- ld ra,0(sp) /* restore return address */
- aaddiu sp,sp,16 /* free stack space */
- aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
- b asm_handle_nat_exception
- .end asm_builtin_checkarraycast
-
-
-/******************* function asm_builtin_aastore ******************************
-* *
-* Does the cast check and eventually throws an exception *
-* a0 = arrayref, a1 = index, a2 = value *
-* *
-*******************************************************************************/
-
- .ent asm_builtin_aastore
-asm_builtin_aastore:
-
- beqz a0,nb_aastore_null /* if null pointer throw exception */
- lw t0,offarraysize(a0) /* load size */
- aaddiu sp,sp,-32 /* allocate stack space */
- sd ra,0(sp) /* save return address */
- asll t1,a1,ashift /* add index*8 to arrayref */
- aaddu t1,a0,t1 /* add index * ashift to arrayref */
- sltu t0,a1,t0 /* do bound check */
- beqz t0,nb_aastore_bound /* if out of bounds throw exception */
- move a1,a2 /* object is second argument */
- sd t1,8(sp) /* save store position */
- sd a1,16(sp) /* save object */
- jal builtin_canstore /* builtin_canstore(arrayref,object) */
- ld ra,0(sp) /* restore return address */
- ld a0,8(sp) /* restore store position */
- ld a1,16(sp) /* restore object */
- aaddiu sp,sp,32 /* free stack space */
- beqz v0,nb_aastore_throw /* if (false) throw exception */
- ast a1,offobjarrdata(a0) /* store objectptr in array */
- j ra /* return */
-
-nb_aastore_null:
- ald xptr,proto_java_lang_NullPointerException
- move xpc,ra /* faulting address is return adress */
- b asm_handle_nat_exception
-
-nb_aastore_bound:
- ald xptr,proto_java_lang_ArrayIndexOutOfBoundsException
- aaddiu sp,sp,32 /* free stack space */
- move xpc,ra /* faulting address is return adress */
- b asm_handle_nat_exception
-
-nb_aastore_throw:
- ald xptr,proto_java_lang_ArrayStoreException
- move xpc,ra /* faulting address is return adress */
- b asm_handle_nat_exception
-
- .end asm_builtin_aastore
-
-
-/******************* function asm_initialize_thread_stack **********************
-* *
-* u1* asm_initialize_thread_stack (void *func, u1 *stack); *
-* *
-* initialize a thread stack *
-* *
-*******************************************************************************/
-
- .ent asm_initialize_thread_stack
-asm_initialize_thread_stack:
-
- aaddiu a1,a1,-14*8 /* allocate save area */
- sd zero, 0*8(a1) /* s0 initalize thread area */
- sd zero, 1*8(a1) /* s1 */
- sd zero, 2*8(a1) /* s2 */
- sd zero, 3*8(a1) /* s3 */
- sd zero, 4*8(a1) /* s4 */
- sd zero, 5*8(a1) /* s5 */
- sd zero, 6*8(a1) /* s6 */
- sd zero, 7*8(a1) /* s7 */
- sd zero, 8*8(a1) /* s8 */
- sd zero, 9*8(a1) /* fs0 */
- sd zero,10*8(a1) /* fs1 */
- sd zero,11*8(a1) /* fs2 */
- sd zero,12*8(a1) /* fs3 */
- sd a0, 13*8(a1)
- move v0,a1
- j ra /* return */
- .end asm_initialize_thread_stack
-
-
-/******************* function asm_perform_threadswitch *************************
-* *
-* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
-* *
-* performs a threadswitch *
-* *
-*******************************************************************************/
-
- .ent asm_perform_threadswitch
-asm_perform_threadswitch:
-
- aaddiu sp,sp,-14*8 /* allocate new stack */
- sd s0, 0*8(sp) /* save saved registers of old thread */
- sd s1, 1*8(sp)
- sd s2, 2*8(sp)
- sd s3, 3*8(sp)
- sd s4, 4*8(sp)
- sd s5, 5*8(sp)
- sd s6, 6*8(sp)
- sd s7, 7*8(sp)
-/* sd s8, 8*8(sp) */
- sdc1 fs0, 9*8(sp)
- sdc1 fs1,10*8(sp)
- sdc1 fs2,11*8(sp)
- sdc1 fs3,12*8(sp)
- sd ra, 13*8(sp)
- ast sp,0(a0) /* save old stack pointer */
- ast sp,0(a2) /* stackTop = old stack pointer */
- ald sp,0(a1) /* load new stack pointer */
- ld s0, 0*8(sp) /* load saved registers of new thread */
- ld s1, 1*8(sp)
- ld s2, 2*8(sp)
- ld s3, 3*8(sp)
- ld s4, 4*8(sp)
- ld s5, 5*8(sp)
- ld s6, 6*8(sp)
- ld s7, 7*8(sp)
-/* ld s8, 8*8(sp) */
- ldc1 fs0, 9*8(sp)
- ldc1 fs1,10*8(sp)
- ldc1 fs2,11*8(sp)
- ldc1 fs3,12*8(sp)
- ld ra, 13*8(sp)
- aaddiu sp,sp,14*8 /* deallocate new stack */
- j ra /* return */
- .end asm_perform_threadswitch
-
-
-/********************* function asm_switchstackandcall *************************
-* *
-* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
-* *
-* Switches to a new stack, calls a function and switches back. *
-* a0 new stack pointer *
-* a1 function pointer *
-* a2 pointer to variable where stack top should be stored *
-* *
-*******************************************************************************/
-
-
- .ent asm_switchstackandcall
-asm_switchstackandcall:
- aaddiu a0,a0,-16 /* allocate new stack */
- sd ra,0(a0) /* save return address on new stack */
- sd sp,8(a0) /* save old stack pointer on new stack */
- sd sp,0(a2) /* save old stack pointer to variable */
- move sp,a0 /* switch to new stack */
-
- move itmp3,a1
- jalr itmp3 /* and call function */
-
- ld ra,0(sp) /* load return address */
- ld sp,8(sp) /* switch to old stack */
-
- j ra /* return */
-
- .end asm_switchstackandcall