- codegendata *cd;
- registerdata *rd;
- exceptionref *er;
- s4 branchmpc;
- s4 targetmpc;
- s4 targetdisp;
- s4 disp;
-
- /* get required compiler data */
-
- cd = jd->cd;
- rd = jd->rd;
-
- /* generate exception stubs */
-
- targetdisp = 0;
-
- for (er = cd->exceptionrefs; er != NULL; er = er->next) {
- /* back-patch the branch to this exception code */
-
- branchmpc = er->branchmpc;
- targetmpc = cd->mcodeptr - cd->mcodebase;
-
- md_codegen_patch_branch(cd, branchmpc, targetmpc);
-
- MCODECHECK(100);
-
- /* Check if the exception is an
- ArrayIndexOutOfBoundsException. If so, move index register
- into REG_ITMP1. */
-
- if (er->reg != -1)
- M_MOV(REG_ITMP1, er->reg);
-
- /* calcuate exception address */
-
- assert((er->branchmpc - 4) % 4 == 0);
- M_ADD_IMM_EXT_MUL4(REG_ITMP2_XPC, REG_PV, (er->branchmpc - 4) / 4);
-
- /* move function to call into REG_ITMP3 */
-
- disp = dseg_add_functionptr(cd, er->function);
- M_DSEG_LOAD(REG_ITMP3, disp);
-
- if (targetdisp == 0) {
- targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
-
- M_MOV(rd->argintregs[0], REG_PV);
- M_MOV(rd->argintregs[1], REG_SP);
-
- if (jd->isleafmethod)
- M_MOV(rd->argintregs[2], REG_LR);
- else
- M_LDR(rd->argintregs[2], REG_SP,
- cd->stackframesize * 4 - SIZEOF_VOID_P);
-
- M_MOV(rd->argintregs[3], REG_ITMP2_XPC);
-
- /* save registers */
- /* TODO: we only need to save LR in leaf methods */
-
- M_STMFD(BITMASK_ARGS | 1<<REG_PV | 1<<REG_LR, REG_SP);
-
- /* move a3 to stack */
-
- M_STR_UPDATE(REG_ITMP1, REG_SP, -4);
-
- /* do the exception call */
-
- M_MOV(REG_LR, REG_PC);
- M_MOV(REG_PC, REG_ITMP3);
-
- M_ADD_IMM(REG_SP, REG_SP, 4);
-
- /* result of stacktrace is our XPTR */
-
- M_MOV(REG_ITMP1_XPTR, REG_RESULT);
-
- /* restore registers */
-
- M_LDMFD(BITMASK_ARGS | 1<<REG_PV | 1<<REG_LR, REG_SP);
-
- disp = dseg_add_functionptr(cd, asm_handle_exception);
- M_DSEG_LOAD(REG_ITMP3, disp);
- M_MOV(REG_PC, REG_ITMP3);
- }
- else {
- disp = (((u4 *) cd->mcodebase) + targetdisp) -
- (((u4 *) cd->mcodeptr) + 2);
-
- M_B(disp);
- }
- }