diff options
Diffstat (limited to 'src/lj_asm_mips.h')
-rw-r--r-- | src/lj_asm_mips.h | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 321d63c0..a3ab2f8e 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -64,19 +64,31 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow) | |||
64 | /* Setup spare long-range jump slots per mcarea. */ | 64 | /* Setup spare long-range jump slots per mcarea. */ |
65 | static void asm_sparejump_setup(ASMState *as) | 65 | static void asm_sparejump_setup(ASMState *as) |
66 | { | 66 | { |
67 | MCode *mxp = as->mcbot; | 67 | MCode *mxp = as->mctop; |
68 | if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) { | 68 | if ((char *)mxp == (char *)as->J->mcarea + as->J->szmcarea) { |
69 | mxp -= MIPS_SPAREJUMP*2; | ||
69 | lj_assertA(MIPSI_NOP == 0, "bad NOP"); | 70 | lj_assertA(MIPSI_NOP == 0, "bad NOP"); |
70 | memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode)); | 71 | memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode)); |
71 | mxp += MIPS_SPAREJUMP*2; | 72 | as->mctop = mxp; |
72 | lj_assertA(mxp < as->mctop, "MIPS_SPAREJUMP too big"); | ||
73 | lj_mcode_sync(as->mcbot, mxp); | ||
74 | lj_mcode_commitbot(as->J, mxp); | ||
75 | as->mcbot = mxp; | ||
76 | as->mclim = as->mcbot + MCLIM_REDZONE; | ||
77 | } | 73 | } |
78 | } | 74 | } |
79 | 75 | ||
76 | static MCode *asm_sparejump_use(MCode *mcarea, MCode tjump) | ||
77 | { | ||
78 | MCode *mxp = (MCode *)((char *)mcarea + ((MCLink *)mcarea)->size); | ||
79 | int slot = MIPS_SPAREJUMP; | ||
80 | while (slot--) { | ||
81 | mxp -= 2; | ||
82 | if (*mxp == tjump) { | ||
83 | return mxp; | ||
84 | } else if (*mxp == MIPSI_NOP) { | ||
85 | *mxp = tjump; | ||
86 | return mxp; | ||
87 | } | ||
88 | } | ||
89 | return NULL; | ||
90 | } | ||
91 | |||
80 | /* Setup exit stub after the end of each trace. */ | 92 | /* Setup exit stub after the end of each trace. */ |
81 | static void asm_exitstub_setup(ASMState *as) | 93 | static void asm_exitstub_setup(ASMState *as) |
82 | { | 94 | { |
@@ -2704,21 +2716,17 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
2704 | patchbranch: | 2716 | patchbranch: |
2705 | p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu); | 2717 | p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu); |
2706 | *p = MIPSI_NOP; /* Replace the load of the exit number. */ | 2718 | *p = MIPSI_NOP; /* Replace the load of the exit number. */ |
2707 | cstop = p; | 2719 | cstop = p+1; |
2708 | if (!cstart) cstart = p-1; | 2720 | if (!cstart) cstart = p-1; |
2709 | } else { /* Branch out of range. Use spare jump slot in mcarea. */ | 2721 | } else { /* Branch out of range. Use spare jump slot in mcarea. */ |
2710 | int i; | 2722 | MCode *mcjump = asm_sparejump_use(mcarea, tjump); |
2711 | for (i = (int)(sizeof(MCLink)/sizeof(MCode)); | 2723 | if (mcjump) { |
2712 | i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2); | 2724 | lj_mcode_sync(mcjump, mcjump+1); |
2713 | i += 2) { | 2725 | delta = mcjump - p; |
2714 | if (mcarea[i] == tjump) { | 2726 | if (((delta + 0x8000) >> 16) == 0) { |
2715 | delta = mcarea+i - p; | ||
2716 | goto patchbranch; | ||
2717 | } else if (mcarea[i] == MIPSI_NOP) { | ||
2718 | mcarea[i] = tjump; | ||
2719 | cstart = mcarea+i; | ||
2720 | delta = mcarea+i - p; | ||
2721 | goto patchbranch; | 2727 | goto patchbranch; |
2728 | } else { | ||
2729 | lj_assertJ(0, "spare jump out of range: -Osizemcode too big"); | ||
2722 | } | 2730 | } |
2723 | } | 2731 | } |
2724 | /* Ignore jump slot overflow. Child trace is simply not attached. */ | 2732 | /* Ignore jump slot overflow. Child trace is simply not attached. */ |