37 #define RBP(x) (0x18 + (x * sizeof(PN)))
43 #define REG(x) (x == 0 ? 0 : (x == 1 ? 2 : x + 2))
47 #define PPC(ins, a, b, c, d) \
48 ASM((ins << 2) | ((a >> 2) & 0x3)); \
49 ASM((a << 5) | (b & 0x1F)); \
51 #define PPC3(ins, a, b, c) \
52 PPC(ins, a, b, c >> 8, c)
53 #define PPC2(ins, a, b) \
54 PPC(ins, a, 0, b >> 8, b)
55 #define PPCN(ins, a) \
57 ASM(a >> 16); ASM(a >> 8); ASM(a)
59 #define PPC_MOV(a, b) \
60 PPC(31, b, a, (b << 3) | 0x3, 0x78); // or rA,rB,rB
62 PPC(31, REG(op.a), REG(op.a), 0x0e, 0x70); \
63 PPC(31, REG(op.b), REG(op.b), 0x0e, 0x70)
64 #define PPC_MATH(do) \
67 PPC(21, REG(op.a), REG(op.a), 0x08, 0x3c); \
68 PPC3(24, REG(op.a), REG(op.a), 1); \
69 PPC(21, REG(op.b), REG(op.b), 0x08, 0x3c); \
70 PPC3(24, REG(op.b), REG(op.b), 1);
71 #define PPC_CMP(cmp) \
73 PPC(31, 7 << 2, REG(op.a), REG(op.b) << 3, 0x40); \
75 PPC2(14, REG(op.a), PN_TRUE); \
77 PPC2(14, REG(op.a), PN_FALSE);
78 #define TAG_JMP(ins, jpos) \
80 jmps[*jmpc].from = asmp[0]->len; \
82 jmps[*jmpc].to = jpos + 1; \
84 } else if (jpos < pos) { \
85 int off = (offs[jpos + 1] - (asmp[0]->len)); \
86 if (ins == 0x48000000) \
87 ASMI(ins | (off & 0x3FFFFFF)); \
89 ASMI(ins | (off & 0xFFFF)); \
95 PPC3(47, 30, 1, 0xFFF8);
99 rsp = -((rsp+31)&~(15));
114 if (asmj[0] == 0x48) {
115 asmj[0] |= (dist >> 24) & 3;
116 asmj[1] = dist >> 16;
230 PPC(11, 7 << 2,
REG(op.
b), 0, 0);
340 PPC3(46, 30, 1, 0xFFF8);
#define PN_TUPLE_AT(t, n)
void potion_ppc_ivars(Potion *P, PN ivars, PNAsm *volatile *asmp)
PN asmb
assembled instructions
void potion_ppc_newtuple(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
PN values
numbers, strings, etc.
void potion_ppc_not(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
record labels to be patched
void potion_ppc_testjmp(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, PN_OP *start, PNJumps *jmps, size_t *offs, int *jmpc)
void potion_ppc_local(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, long reg, long arg)
void potion_ppc_bitn(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_message(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_test(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_sub(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_setupval(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long lregs)
void potion_ppc_tailcall(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
#define REG(x)
The EABI reserves GPR1 for a stack pointer, GPR3-GPR7 for function argument passing, and GPR3 for function return values.
void potion_ppc_setup(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp)
void potion_ppc_global(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_neq(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_jmpedit(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, unsigned char *asmj, int dist)
void potion_ppc_getlocal(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long regs)
void potion_ppc_mcache(Potion *P, vPN(Vtable) vt, PNAsm *volatile *asmp)
void potion_ppc_setlocal(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long regs)
void potion_ppc_def(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_mult(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
#define REG_TMP
The scratch space, register 3, is referred to as rD in the notation.
void potion_ppc_lt(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
#define PPC3(ins, a, b, c)
#define TAG_JMP(ins, jpos)
the Potion VM instruction set (heavily based on Lua's)
void potion_ppc_finish(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp)
void potion_ppc_call(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_class(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_bitr(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_self(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_gte(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_test_asm(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, int test)
void potion_ppc_setpath(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_rem(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_add(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
#define PPC(ins, a, b, c, d)
void potion_ppc_eq(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_stack(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, long rsp)
void potion_ppc_registers(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, long start)
void potion_ppc_search(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_cmp(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_callset(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
a prototype is compiled source code, a closure block (lambda) non-volatile.
void potion_ppc_upvals(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, long lregs, long start, int upc)
void potion_ppc_div(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_lte(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_jmp(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, PN_OP *start, PNJumps *jmps, size_t *offs, int *jmpc)
void potion_ppc_pow(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_getupval(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long lregs)
#define PN_OP_AT(asmb, n)
int a
< the op. See vm.c http://www.lua.org/doc/jucs05.pdf
the global interpreter state P. currently singleton (not threads yet)
void potion_ppc_settable(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_settuple(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_bind(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_named(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_loadk(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_gettuple(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_gettable(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_bitl(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_return(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_newlick(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_gt(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
int b
optional arg, the message
void potion_ppc_move(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_loadpn(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos)
void potion_ppc_getpath(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, long start)
void potion_ppc_method(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_OP **pos, long lregs, long start, long regs)
void potion_ppc_notjmp(Potion *P, struct PNProto *volatile f, PNAsm *volatile *asmp, PN_SIZE pos, PN_OP *start, PNJumps *jmps, size_t *offs, int *jmpc)
PN_OP - a compressed three-address op (as 32bit int bitfield) TODO: expand to 64bit, check jit then.