- 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 */
- lda a3,0(zero)
- lda a4,1(zero)
- 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 */
-
- ldl itmp3,offclassloaded(a1)
- bne itmp3,L_class_loaded
-
- subq sp,8*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)
- stq a1,7*8(sp)
-
- mov a1,a0
-
- br ra,L_class_load_ra /* set ra for gp loading */
-L_class_load_ra:
- ldgp gp,0(ra) /* load gp */
- jsr ra,load_class_bootstrap
-
- 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)
- ldq a1,7*8(sp)
- addq sp,8*8,sp /* deallocate stack */
-
-L_class_loaded:
- ldl itmp3,offclasslinked(a1)
- subq sp,8*8,sp /* allocate stack */
- stq a1,7*8(sp)
- bne itmp3,L_class_linked
-
- 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)
-
- mov a1,a0
-
- br ra,L_class_link_ra /* set ra for gp loading */
-L_class_link_ra:
- ldgp gp,0(ra) /* load gp */
- jsr ra,link_class
-
- 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)
-
-L_class_linked:
-_crit_restart1:
- ldq a1,7*8(sp)
-_crit_begin1:
- ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
- ldq a1,offclassvftbl(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) */
-_crit_end1:
- subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
- cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
- addq sp,8*8,sp /* deallocate stack */
- 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 */
-
-#if defined(USE_THREADS)
- 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) */
+L_asm_handle_exception: /* required for PIC code */
+ lda sp,-(ARG_CNT+TMP_CNT)*8(sp) /* create maybe-leaf stackframe */
+
+ SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
+ SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
+
+ lda sp,-6*8(sp) /* keep stack 16-byte aligned */
+ stq xptr,0*8(sp) /* save xptr */
+ stq pv,2*8(sp) /* save PV */
+ stq ra,3*8(sp) /* save RA */
+ lda t0,1(zero) /* set maybe-leaf flag */
+ stq t0,4*8(sp) /* save maybe-leaf flag */
+
+ br ra,L_asm_handle_exception_load_gp_2
+L_asm_handle_exception_load_gp_2:
+ ldgp gp,0(ra) /* load gp */
+
+ mov xptr,a0 /* pass xptr */
+ mov xpc,a1 /* pass xpc */
+ mov pv,a2 /* pass PV */
+ lda a3,(ARG_CNT+TMP_CNT+6)*8(sp)/* pass Java SP */
+
+L_asm_handle_exception_continue:
+ jsr ra,exceptions_handle_exception
+
+ beq v0,L_asm_handle_exception_not_catched
+
+ mov v0,xpc /* move handlerpc into xpc */
+ ldq xptr,0*8(sp) /* restore xptr */
+ ldq pv,2*8(sp) /* restore PV */
+ ldq ra,3*8(sp) /* restore RA */
+ ldq t0,4*8(sp) /* get maybe-leaf flag */
+ lda sp,6*8(sp) /* free stack frame */
+
+ beq t0,L_asm_handle_exception_no_leaf
+
+ RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
+ RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */