Index: cacao-0.99.3/src/vm/jit/arm/codegen.h =================================================================== --- cacao-0.99.3.orig/src/vm/jit/arm/codegen.h 2009-03-21 20:17:46.000000000 +0100 +++ cacao-0.99.3/src/vm/jit/arm/codegen.h 2009-03-21 20:18:19.000000000 +0100 @@ -1107,15 +1107,22 @@ /* M_RECOMPUTE_PV: used to recompute our PV (we use the IP for this) out of the current PC ATTENTION: if you change this, you have to look at other functions as well! - Following things depend on it: asm_call_jit_compiler(); codegen_findmethod(); + Following things depend on it: md_codegen_get_pv_from_pc(); */ #define M_RECOMPUTE_PV(disp) \ disp += 8; /* we use PC relative addr. */ \ assert((disp & 0x03) == 0); \ assert(disp >= 0 && disp <= 0x03ffffff); \ - M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 2, 1)); \ - if (disp > 0x000003ff) M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 10, 5)); \ - if (disp > 0x0003ffff) M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 18, 9)); \ + if (disp > 0x0003ffff) { \ + M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 18, 9)); \ + M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 10, 5)); \ + M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 2, 1)); \ + } else if (disp > 0x000003ff) { \ + M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 10, 5)); \ + M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 2, 1)); \ + } else { \ + M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 2, 1)); \ + } /* M_INTMOVE: generates an integer-move from register a to b. Index: cacao-0.99.3/src/vm/jit/arm/md.h =================================================================== --- cacao-0.99.3.orig/src/vm/jit/arm/md.h 2009-03-21 20:17:47.000000000 +0100 +++ cacao-0.99.3/src/vm/jit/arm/md.h 2009-03-21 20:18:19.000000000 +0100 @@ -68,30 +68,40 @@ inline static u1 *md_codegen_get_pv_from_pc(u1 *ra) { + u4 *pc; u1 *pv; - u4 mcode1, mcode2, mcode3; + u4 mcode; + int mcode_idx; + pc = (u4*) ra; pv = ra; /* this can either be a RECOMPUTE_IP in JIT code or a fake in asm_calljavafunction */ - mcode1 = *((u4*) ra); - if ((mcode1 & 0xffffff00) == 0xe24fcf00 /*sub ip,pc,#__*/) - pv -= (s4) ((mcode1 & 0x000000ff) << 2); - else if ((mcode1 & 0xffffff00) == 0xe24fc000 /*sub ip,pc,#__*/) - pv -= (s4) (mcode1 & 0x000000ff); + mcode_idx = 0; + mcode = pc[0]; + + /* if this was shifted by 18 bits, we have to load additional instructions */ + if ((mcode & 0xfff0ff00) == 0xe240c700 /*sub ip,??,#__*/) { + pv -= (s4) ((mcode & 0x000000ff) << 18); + mcode = pc[++mcode_idx]; + } + + /* if this was shifted by 10 bits, we have to load additional instructions */ + if ((mcode & 0xfff0ff00) == 0xe240cb00 /*sub ip,??,#__*/) { + pv -= (s4) ((mcode & 0x000000ff) << 10); + mcode = pc[++mcode_idx]; + } + + /* this is the default path with just one instruction, shifted by 2 or no bits */ + if ((mcode & 0xfff0ff00) == 0xe240cf00 /*sub ip,??,#__*/) + pv -= (s4) ((mcode & 0x000000ff) << 2); + else if ((mcode & 0xffffff00) == 0xe24fc000 /*sub ip,pc,#__*/) + pv -= (s4) (mcode & 0x000000ff); else { /* if this happens, we got an unexpected instruction at (*ra) */ - vm_abort("Unable to find method: %p (instr=%x)", ra, mcode1); + vm_abort("Unable to find method: %p (instr=%x)", ra, mcode); } - /* if we have a RECOMPUTE_IP there can be more than one instruction */ - mcode2 = *((u4*) (ra + 4)); - mcode3 = *((u4*) (ra + 8)); - if ((mcode2 & 0xffffff00) == 0xe24ccb00 /*sub ip,ip,#__*/) - pv -= (s4) ((mcode2 & 0x000000ff) << 10); - if ((mcode3 & 0xffffff00) == 0xe24cc700 /*sub ip,ip,#__*/) - pv -= (s4) ((mcode3 & 0x000000ff) << 18); - /* we used PC-relative adressing; but now it is LR-relative */ pv += 8;