aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_ppc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_ppc.h')
-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 dc092db2..32546c78 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -1852,6 +1852,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
1852 1852
1853/* -- GC handling --------------------------------------------------------- */ 1853/* -- GC handling --------------------------------------------------------- */
1854 1854
1855/* Marker to prevent patching the GC check exit. */
1856#define PPC_NOPATCH_GC_CHECK PPCI_ORIS
1857
1855/* Check GC threshold and do one or more GC steps. */ 1858/* Check GC threshold and do one or more GC steps. */
1856static void asm_gc_check(ASMState *as) 1859static void asm_gc_check(ASMState *as)
1857{ 1860{
@@ -1863,6 +1866,7 @@ static void asm_gc_check(ASMState *as)
1863 l_end = emit_label(as); 1866 l_end = emit_label(as);
1864 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */ 1867 /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
1865 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */ 1868 asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
1869 *--as->mcp = PPC_NOPATCH_GC_CHECK;
1866 emit_ai(as, PPCI_CMPWI, RID_RET, 0); 1870 emit_ai(as, PPCI_CMPWI, RID_RET, 0);
1867 args[0] = ASMREF_TMP1; /* global_State *g */ 1871 args[0] = ASMREF_TMP1; /* global_State *g */
1868 args[1] = ASMREF_TMP2; /* MSize steps */ 1872 args[1] = ASMREF_TMP2; /* MSize steps */
@@ -2124,7 +2128,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2124 MCode *px = exitstub_trace_addr(T, exitno); 2128 MCode *px = exitstub_trace_addr(T, exitno);
2125 MCode *cstart = NULL; 2129 MCode *cstart = NULL;
2126 MCode *mcarea = lj_mcode_patch(J, p, 0); 2130 MCode *mcarea = lj_mcode_patch(J, p, 0);
2127 int clearso = 0; 2131 int clearso = 0, patchlong = 1;
2128 for (; p < pe; p++) { 2132 for (; p < pe; p++) {
2129 /* Look for exitstub branch, try to replace with branch to target. */ 2133 /* Look for exitstub branch, try to replace with branch to target. */
2130 uint32_t ins = *p; 2134 uint32_t ins = *p;
@@ -2136,7 +2140,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2136 delta -= sizeof(MCode); 2140 delta -= sizeof(MCode);
2137 } 2141 }
2138 /* Many, but not all short-range branches can be patched directly. */ 2142 /* Many, but not all short-range branches can be patched directly. */
2139 if (((delta + 0x8000) >> 16) == 0) { 2143 if (p[-1] == PPC_NOPATCH_GC_CHECK) {
2144 patchlong = 0;
2145 } else if (((delta + 0x8000) >> 16) == 0) {
2140 *p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) | 2146 *p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
2141 ((delta & 0x8000) * (PPCF_Y/0x8000)); 2147 ((delta & 0x8000) * (PPCF_Y/0x8000));
2142 if (!cstart) cstart = p; 2148 if (!cstart) cstart = p;
@@ -2149,7 +2155,8 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2149 if (!cstart) cstart = p; 2155 if (!cstart) cstart = p;
2150 } 2156 }
2151 } 2157 }
2152 { /* Always patch long-range branch in exit stub itself. */ 2158 /* Always patch long-range branch in exit stub itself. Except, if we can't. */
2159 if (patchlong) {
2153 ptrdiff_t delta = (char *)target - (char *)px - clearso; 2160 ptrdiff_t delta = (char *)target - (char *)px - clearso;
2154 lua_assert(((delta + 0x02000000) >> 26) == 0); 2161 lua_assert(((delta + 0x02000000) >> 26) == 0);
2155 *px = PPCI_B | ((uint32_t)delta & 0x03ffffffu); 2162 *px = PPCI_B | ((uint32_t)delta & 0x03ffffffu);