Currently all architecures have there own core.jit. These are very similar, e.g. checking for MAPped registers, but differ depending on the processor architecure: basically we have 3 register machines (alpha, arm, ppc, sparc) and a 2 register machine (i386).
My proposal is to write a universal core.jit, which provides the basic functionality. e.g. Parrot_add_i_i_i { if (MAP[1] && MAP[2] && MAP[3]) { #ifdef jit_emit_add_rrr_i /* 3 reg machine */ jit_emit_add_rrr_i(MAP(2), MAP(3), MAP(1)); #else jit_emit_mov_rr_i(MAP(2), MAP(1)); jit_emit_add_rr_i(MAP(3), MAP(1)); #endif } ... The implementation of these jit_emit_ops would stay in jit_emit.h. Proposed naming of ops: jit_emit_<op>_<rmi>_<in>(...) <op> operations mov, add, sub, mul, ... <rmi> register, memory, immediate, for all parameters (source, dest) or (source, source, dest) <in> integer (or pointer...) or number jit_emit_mov_rm_n(<reg>, <mem>) (store processor reg to parrot num_reg at mem) jit_emit_mov_mr_i(<mem>, <reg>) (load processor reg from parrot int_reg at mem) The <reg>s would be taken from a list of processor regs, either the MAPed ones, or 1 or 2 scratch registers, depending on architecture. jit_emit_jmp_p(<cond>, offset) jit_emit_call_p(offset) Jump to or call parrot funcs at offset. <cond> : cond_always, cond_lt,le,gt,ge,eq,ne jit_emit_push_<rm>(.., &SP_diff) jit_emit_call_c(addr) jit_emit_call_vtable(mem_of_pmc_reg, int n) jit_emit_add_SP(SP_diff) jit_emit_ret Push (or whatever) params on stack, preparing for a native call, correct SP after return. With these ops, all the current functionality could be in one file, all the register mapping would be centralized. If something doesn't fit, it could be undefined for this architecture, the implementation would then be in jit_emit.h. Comments welcome leo