aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_ppc.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_asm_ppc.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 77ab09d6..0952ca26 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -2067,6 +2067,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
2067 2067
2068/* -- GC handling --------------------------------------------------------- */ 2068/* -- GC handling --------------------------------------------------------- */
2069 2069
2070/* Marker to prevent patching the GC check exit. */
2071#define PPC_NOPATCH_GC_CHECK PPCI_ORIS
2072
2070/* Check GC threshold and do one or more GC steps. */ 2073/* Check GC threshold and do one or more GC steps. */
2071static void asm_gc_check(ASMState *as) 2074static void asm_gc_check(ASMState *as)
2072{ 2075{
@@ -2078,6 +2081,7 @@ static void asm_gc_check(ASMState *as)
2078 l_end = emit_label(as); 2081 l_end = emit_label(as);
2079 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */ 2082 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
2080 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */ 2083 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
2084 *--as->mcp = PPC_NOPATCH_GC_CHECK;
2081 emit_ai(as, PPCI_CMPWI, RID_RET, 0); 2085 emit_ai(as, PPCI_CMPWI, RID_RET, 0);
2082 args[0] = ASMREF_TMP1; /* global_State *g */ 2086 args[0] = ASMREF_TMP1; /* global_State *g */
2083 args[1] = ASMREF_TMP2; /* MSize steps */ 2087 args[1] = ASMREF_TMP2; /* MSize steps */
@@ -2217,7 +2221,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2217 MCode *px = exitstub_trace_addr(T, exitno); 2221 MCode *px = exitstub_trace_addr(T, exitno);
2218 MCode *cstart = NULL; 2222 MCode *cstart = NULL;
2219 MCode *mcarea = lj_mcode_patch(J, p, 0); 2223 MCode *mcarea = lj_mcode_patch(J, p, 0);
2220 int clearso = 0; 2224 int clearso = 0, patchlong = 1;
2221 for (; p < pe; p++) { 2225 for (; p < pe; p++) {
2222 /* Look for exitstub branch, try to replace with branch to target. */ 2226 /* Look for exitstub branch, try to replace with branch to target. */
2223 uint32_t ins = *p; 2227 uint32_t ins = *p;
@@ -2229,7 +2233,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2229 delta -= sizeof(MCode); 2233 delta -= sizeof(MCode);
2230 } 2234 }
2231 /* Many, but not all short-range branches can be patched directly. */ 2235 /* Many, but not all short-range branches can be patched directly. */
2232 if (((delta + 0x8000) >> 16) == 0) { 2236 if (p[-1] == PPC_NOPATCH_GC_CHECK) {
2237 patchlong = 0;
2238 } else if (((delta + 0x8000) >> 16) == 0) {
2233 *p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) | 2239 *p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
2234 ((delta & 0x8000) * (PPCF_Y/0x8000)); 2240 ((delta & 0x8000) * (PPCF_Y/0x8000));
2235 if (!cstart) cstart = p; 2241 if (!cstart) cstart = p;
@@ -2243,7 +2249,8 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2243 if (!cstart) cstart = p; 2249 if (!cstart) cstart = p;
2244 } 2250 }
2245 } 2251 }
2246 { /* Always patch long-range branch in exit stub itself. */ 2252 /* Always patch long-range branch in exit stub itself. Except, if we can't. */
2253 if (patchlong) {
2247 ptrdiff_t delta = (char *)target - (char *)px - clearso; 2254 ptrdiff_t delta = (char *)target - (char *)px - clearso;
2248 lj_assertJ(((delta + 0x02000000) >> 26) == 0, 2255 lj_assertJ(((delta + 0x02000000) >> 26) == 0,
2249 "branch target out of range"); 2256 "branch target out of range");