summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Ushakov <uwe@stderr.spb.ru>2017-08-31 20:22:08 +0300
committerValery Ushakov <uwe@stderr.spb.ru>2017-08-31 20:22:08 +0300
commitaf364d9265f84faf807f5db6b8db6936a92124c6 (patch)
tree9164e6e386ebe1b763d15c41ced745055fe19497
parent2c1c5550090353a79298acaab260482d239afb54 (diff)
Save/restore callee-saved registers around JIT code comvec.origin/NetBSD/powerpcNetBSD/powerpc
Makes JIT work on NetBSD/macppc (requires "macjit" set in the emu config file). Protected with #ifdef __ELF__ as I don't know what ABI Mac OS X uses on ppc and can't test there (note also that OS X config file explicitely disables jit).
-rw-r--r--libinterp/comp-power.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/libinterp/comp-power.c b/libinterp/comp-power.c
index a53b0bf8..993542d7 100644
--- a/libinterp/comp-power.c
+++ b/libinterp/comp-power.c
@@ -31,6 +31,10 @@
#define MFSPR(s, d) gen(XO(31,339) | ((d)<<21) | ((s)<<11))
#define MTSPR(s, d) gen(XO(31,467) | ((s)<<21) | ((d)<<11));
+#define MFCR(d) gen(XO(31,19) | ((d)<<21))
+#define MTCRF(s, mask) gen(XO(31,144) | ((s)<<21) | ((mask)<<12))
+#define MTCR(s) MTCRF(s, 0xff)
+
#define SLWI(d,a,n) gen(slw((d),(a),(n),0))
#define LRET() gen(Oblr)
@@ -1636,7 +1640,7 @@ comp(Inst *i)
}
enum {
- PREFLEN = 20, /* max instruction words in comvec */
+ PREFLEN = 64, /* max instruction words in comvec */
};
static void
@@ -1649,6 +1653,45 @@ preamble(void)
s = code = malloc(PREFLEN*sizeof(*code));
if(s == nil)
error(exNomem);
+
+#ifdef __ELF__
+ if(macjit) {
+ ulong *cp;
+ int r;
+
+ /*
+ * ELF frame:
+ * 0(%sp) - back chain
+ * 4(%sp) - callee's LR save slot
+ * 8(%sp) to 36(%sp) - 8 words of parameter list area
+ * 40(%sp) to 48(%sp) - pad to 16 byte alignment/local vars
+ */
+ mfspr(Ro1, Rlr);
+ AIRR(Ostw, Ro1, Rsp,4);
+ AIRR(Ostwu, Rsp, Rsp,-128);
+
+ MFCR(Ro1);
+ AIRR(Ostw, Ro1, Rsp,52);
+ for (r = 14; r < 32; ++r)
+ AIRR(Ostw, r, Rsp,r*4);
+
+ cp = code;
+ gen(Ob | Lk);
+
+ AIRR(Olwz, Ro1, Rsp,52);
+ MTCR(Ro1);
+ for (r = 14; r < 32; ++r)
+ AIRR(Olwz, r, Rsp,r*4);
+ AIRR(Oaddi, Rsp, Rsp, 128);
+
+ AIRR(Olwz, Ro1, Rsp,4);
+ mtspr(Rlr, Ro1);
+ LRET();
+
+ PATCH(cp);
+ }
+#endif /* __ELF__ */
+
ldc((ulong)&R, Rreg);
SETR0();
mfspr(Rlink, Rlr);