mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
MIPS: Add interpreter. Enable MIPS build rules.
This commit is contained in:
parent
7d2774e4c5
commit
5bed11e6b4
@ -408,8 +408,7 @@ ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T)
|
||||
ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h
|
||||
ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
|
||||
ALL_DYNGEN= buildvm_x86.h buildvm_x64.h buildvm_x64win.h buildvm_arm.h \
|
||||
buildvm_ppc.h buildvm_ppcspe.h
|
||||
###ALL_DYNGEN+= buildvm_mips.h
|
||||
buildvm_ppc.h buildvm_ppcspe.h buildvm_mips.h
|
||||
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
|
||||
ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
|
||||
|
||||
@ -502,7 +501,7 @@ distclean: clean
|
||||
$(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_ARM) -o buildvm_arm.h buildvm_arm.dasc
|
||||
$(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPC) -o buildvm_ppc.h buildvm_ppc.dasc
|
||||
$(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_PPCSPE) -o buildvm_ppcspe.h buildvm_ppcspe.dasc
|
||||
@### $(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_MIPS) -o buildvm_mips.h buildvm_mips.dasc
|
||||
$(Q)$(DASM) $(DASM_DISTFLAGS) $(DASM_FLAGS_MIPS) -o buildvm_mips.h buildvm_mips.dasc
|
||||
|
||||
depend:
|
||||
@for file in $(ALL_HDRGEN) $(ALL_DYNGEN); do \
|
||||
|
@ -100,8 +100,9 @@ lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \
|
||||
lj_bc.h lj_jit.h lj_ir.h
|
||||
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h \
|
||||
lj_ffdef.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \
|
||||
lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \
|
||||
lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_vm.h luajit.h
|
||||
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
|
||||
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
|
||||
@ -191,9 +192,9 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
|
||||
lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
|
||||
lj_debug.h lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h \
|
||||
lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_debug.c \
|
||||
lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c \
|
||||
lj_vmevent.h lj_vmmath.c lj_api.c lj_bcdump.h lj_parse.h lj_lex.c \
|
||||
lualib.h lj_parse.c lj_bcread.c lj_bcwrite.c lj_ctype.c lj_ccallback.h \
|
||||
lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c lj_ccallback.h luajit.h \
|
||||
lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_api.c lj_bcdump.h lj_parse.h \
|
||||
lj_lex.c lualib.h lj_parse.c lj_bcread.c lj_bcwrite.c lj_ctype.c \
|
||||
lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \
|
||||
lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \
|
||||
lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h \
|
||||
|
@ -120,7 +120,10 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
|
||||
exit(1);
|
||||
}
|
||||
#elif LJ_TARGET_MIPS
|
||||
UNUSED(sym); /* NYI */
|
||||
fprintf(stderr,
|
||||
"Error: unsupported opcode %08x for %s symbol relocation.\n",
|
||||
ins, sym);
|
||||
exit(1);
|
||||
#else
|
||||
#error "missing relocation support for this architecture"
|
||||
#endif
|
||||
@ -200,6 +203,9 @@ void emit_asm(BuildCtx *ctx)
|
||||
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
|
||||
".pad #28\n");
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS
|
||||
fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
|
||||
#endif
|
||||
|
||||
for (i = rel = 0; i < ctx->nsym; i++) {
|
||||
int32_t ofs = ctx->sym[i].ofs;
|
||||
|
4114
src/buildvm_mips.dasc
Normal file
4114
src/buildvm_mips.dasc
Normal file
File diff suppressed because it is too large
Load Diff
7245
src/buildvm_mips.h
Normal file
7245
src/buildvm_mips.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -591,8 +591,10 @@ LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux)
|
||||
|
||||
/* Inline declarations. */
|
||||
LJ_ASMF void lj_ff_coroutine_wrap_aux(void);
|
||||
#if !(LJ_TARGET_MIPS && defined(ljamalg_c))
|
||||
LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
|
||||
lua_State *co);
|
||||
#endif
|
||||
|
||||
/* Error handler, called from assembler VM. */
|
||||
void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co)
|
||||
|
@ -188,13 +188,14 @@
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS
|
||||
|
||||
#define LJ_ARCH_NAME "mips"
|
||||
#define LJ_ARCH_BITS 32
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
|
||||
#define LJ_ARCH_NAME "mipsel"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#else
|
||||
#define LJ_ARCH_NAME "mips"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#endif
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#define LJ_TARGET_MIPS 1
|
||||
#define LJ_TARGET_EHRETREG 4
|
||||
@ -203,7 +204,6 @@
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE
|
||||
#define LJ_ARCH_NOFFI 1
|
||||
#define LJ_ARCH_NOJIT 1
|
||||
|
||||
#else
|
||||
|
@ -290,6 +290,59 @@
|
||||
goto done; \
|
||||
}
|
||||
|
||||
#elif LJ_TARGET_MIPS
|
||||
/* -- MIPS calling conventions -------------------------------------------- */
|
||||
|
||||
#define CCALL_HANDLE_STRUCTRET \
|
||||
cc->retref = 1; /* Return all structs by reference. */ \
|
||||
cc->gpr[ngpr++] = (GPRArg)dp;
|
||||
|
||||
#define CCALL_HANDLE_COMPLEXRET \
|
||||
/* Complex values are returned in 1 or 2 FPRs. */ \
|
||||
cc->retref = 0;
|
||||
|
||||
#define CCALL_HANDLE_COMPLEXRET2 \
|
||||
if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \
|
||||
((float *)dp)[0] = cc->fpr[0].f; \
|
||||
((float *)dp)[1] = cc->fpr[1].f; \
|
||||
} else { /* Copy complex double from FPRs. */ \
|
||||
((double *)dp)[0] = cc->fpr[0].d; \
|
||||
((double *)dp)[1] = cc->fpr[1].d; \
|
||||
}
|
||||
|
||||
#define CCALL_HANDLE_STRUCTARG \
|
||||
/* Pass all structs by value in registers and/or on the stack. */
|
||||
|
||||
#define CCALL_HANDLE_COMPLEXARG \
|
||||
/* Pass complex by value in 2 or 4 GPRs. */
|
||||
|
||||
#define CCALL_HANDLE_REGARG \
|
||||
if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \
|
||||
/* Try to pass argument in FPRs. */ \
|
||||
dp = n == 1 ? (void *)&cc->fpr[nfpr].f : (void *)&cc->fpr[nfpr].d; \
|
||||
nfpr++; ngpr += n; \
|
||||
goto done; \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
nfpr = CCALL_NARG_FPR; \
|
||||
if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
|
||||
if (ngpr < maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
if (ngpr + n > maxgpr) { \
|
||||
nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
|
||||
if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
|
||||
ngpr = maxgpr; \
|
||||
} else { \
|
||||
ngpr += n; \
|
||||
} \
|
||||
goto done; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CCALL_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
sp = (uint8_t *)&cc->fpr[0].f;
|
||||
|
||||
#else
|
||||
#error "Missing calling convention definitions for this architecture"
|
||||
#endif
|
||||
@ -622,12 +675,12 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
|
||||
}
|
||||
if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR)
|
||||
sp += (CTSIZE_PTR - ctr->size);
|
||||
#ifdef CCALL_HANDLE_RET
|
||||
CCALL_HANDLE_RET
|
||||
#endif
|
||||
#if CCALL_NUM_FPR
|
||||
if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
|
||||
sp = (uint8_t *)&cc->fpr[0];
|
||||
#endif
|
||||
#ifdef CCALL_HANDLE_RET
|
||||
CCALL_HANDLE_RET
|
||||
#endif
|
||||
/* No reference types end up here, so there's no need for the CTypeID. */
|
||||
lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
|
||||
|
@ -80,6 +80,21 @@ typedef double FPRArg;
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
|
||||
#elif LJ_TARGET_MIPS
|
||||
|
||||
#define CCALL_NARG_GPR 4
|
||||
#define CCALL_NARG_FPR 2
|
||||
#define CCALL_NRET_GPR 2
|
||||
#define CCALL_NRET_FPR 2
|
||||
#define CCALL_SPS_EXTRA 7
|
||||
#define CCALL_SPS_FREE 1
|
||||
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
||||
} FPRArg;
|
||||
|
||||
#else
|
||||
#error "Missing calling convention definitions for this architecture"
|
||||
#endif
|
||||
|
@ -57,6 +57,13 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
|
||||
#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
|
||||
#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
|
||||
|
||||
#elif LJ_TARGET_MIPS
|
||||
|
||||
#define CALLBACK_MCODE_HEAD 24
|
||||
#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot))
|
||||
#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
|
||||
#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
|
||||
|
||||
#else
|
||||
|
||||
/* Missing support for this architecture. */
|
||||
@ -158,6 +165,25 @@ static void callback_mcode_init(global_State *g, uint32_t *page)
|
||||
}
|
||||
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
||||
}
|
||||
#elif LJ_TARGET_MIPS
|
||||
static void callback_mcode_init(global_State *g, uint32_t *page)
|
||||
{
|
||||
uint32_t *p = page;
|
||||
void *target = (void *)lj_vm_ffi_callback;
|
||||
MSize slot;
|
||||
*p++ = MIPSI_SW | MIPSF_T(RID_R1)|MIPSF_S(RID_SP) | 0;
|
||||
*p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (u32ptr(target) >> 16);
|
||||
*p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (u32ptr(g) >> 16);
|
||||
*p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) |(u32ptr(target)&0xffff);
|
||||
*p++ = MIPSI_JR | MIPSF_S(RID_R3);
|
||||
*p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | (u32ptr(g)&0xffff);
|
||||
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
||||
*p = MIPSI_B | ((page-p-1) & 0x0000ffffu);
|
||||
p++;
|
||||
*p++ = MIPSI_LI | MIPSF_T(RID_R1) | slot;
|
||||
}
|
||||
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
||||
}
|
||||
#else
|
||||
/* Missing support for this architecture. */
|
||||
#define callback_mcode_init(g, p) UNUSED(p)
|
||||
@ -308,6 +334,27 @@ void lj_ccallback_mcode_free(CTState *cts)
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
*(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
|
||||
|
||||
#elif LJ_TARGET_MIPS
|
||||
|
||||
#define CALLBACK_HANDLE_REGARG \
|
||||
if (isfp && nfpr < CCALL_NARG_FPR) { /* Try to pass argument in FPRs. */ \
|
||||
sp = (void *)((uint8_t *)&cts->cb.fpr[nfpr] + ((LJ_BE && n==1) ? 4 : 0)); \
|
||||
nfpr++; ngpr += n; \
|
||||
goto done; \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
nfpr = CCALL_NARG_FPR; \
|
||||
if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
sp = &cts->cb.gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CALLBACK_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
((float *)dp)[1] = *(float *)dp;
|
||||
|
||||
#else
|
||||
#error "Missing calling convention definitions for this architecture"
|
||||
#endif
|
||||
|
@ -8,6 +8,10 @@
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_func.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_tab.h"
|
||||
#include "lj_meta.h"
|
||||
#include "lj_debug.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_frame.h"
|
||||
@ -16,6 +20,9 @@
|
||||
#if LJ_HASJIT
|
||||
#include "lj_jit.h"
|
||||
#endif
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ccallback.h"
|
||||
#endif
|
||||
#include "lj_trace.h"
|
||||
#include "lj_dispatch.h"
|
||||
#include "lj_vm.h"
|
||||
@ -26,6 +33,18 @@ LJ_STATIC_ASSERT(GG_NUM_ASMFF == FF_NUM_ASMFUNC);
|
||||
|
||||
/* -- Dispatch table management ------------------------------------------- */
|
||||
|
||||
#if LJ_TARGET_MIPS
|
||||
#include <math.h>
|
||||
LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
|
||||
lua_State *co);
|
||||
|
||||
#define GOTFUNC(name) (ASMFunction)name,
|
||||
static const ASMFunction dispatch_got[] = {
|
||||
GOTDEF(GOTFUNC)
|
||||
};
|
||||
#undef GOTFUNC
|
||||
#endif
|
||||
|
||||
/* Initialize instruction dispatch table and hot counters. */
|
||||
void lj_dispatch_init(GG_State *GG)
|
||||
{
|
||||
@ -44,6 +63,9 @@ void lj_dispatch_init(GG_State *GG)
|
||||
GG->g.bc_cfunc_ext = GG->g.bc_cfunc_int = BCINS_AD(BC_FUNCC, LUA_MINSTACK, 0);
|
||||
for (i = 0; i < GG_NUM_ASMFF; i++)
|
||||
GG->bcff[i] = BCINS_AD(BC__MAX+i, 0, 0);
|
||||
#if LJ_TARGET_MIPS
|
||||
memcpy(GG->got, dispatch_got, LJ_GOT__MAX*4);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LJ_HASJIT
|
||||
|
@ -12,6 +12,41 @@
|
||||
#include "lj_jit.h"
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_MIPS
|
||||
/* Need our own global offset table for the dreaded MIPS calling conventions. */
|
||||
#if LJ_HASJIT
|
||||
#define JITGOTDEF(_) _(lj_trace_exit) _(lj_trace_hot)
|
||||
#else
|
||||
#define JITGOTDEF(_)
|
||||
#endif
|
||||
#if LJ_HASFFI
|
||||
#define FFIGOTDEF(_) \
|
||||
_(lj_meta_equal_cd) _(lj_ccallback_enter) _(lj_ccallback_leave)
|
||||
#else
|
||||
#define FFIGOTDEF(_)
|
||||
#endif
|
||||
#define GOTDEF(_) \
|
||||
_(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \
|
||||
_(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \
|
||||
_(pow) _(fmod) _(ldexp) \
|
||||
_(lj_dispatch_call) _(lj_dispatch_ins) _(lj_err_throw) \
|
||||
_(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \
|
||||
_(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \
|
||||
_(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \
|
||||
_(lj_meta_for) _(lj_meta_len) _(lj_meta_tget) _(lj_meta_tset) \
|
||||
_(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) _(lj_str_new) \
|
||||
_(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) _(lj_tab_new) \
|
||||
_(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
|
||||
JITGOTDEF(_) FFIGOTDEF(_)
|
||||
|
||||
enum {
|
||||
#define GOTENUM(name) LJ_GOT_##name,
|
||||
GOTDEF(GOTENUM)
|
||||
#undef GOTENUM
|
||||
LJ_GOT__MAX
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Type of hot counter. Must match the code in the assembler VM. */
|
||||
/* 16 bits are sufficient. Only 0.0015% overhead with maximum slot penalty. */
|
||||
typedef uint16_t HotCount;
|
||||
@ -35,6 +70,9 @@ typedef uint16_t HotCount;
|
||||
typedef struct GG_State {
|
||||
lua_State L; /* Main thread. */
|
||||
global_State g; /* Global state. */
|
||||
#if LJ_TARGET_MIPS
|
||||
ASMFunction got[LJ_GOT__MAX]; /* Global offset table. */
|
||||
#endif
|
||||
#if LJ_HASJIT
|
||||
jit_State J; /* JIT state. */
|
||||
HotCount hotcount[HOTCOUNT_SIZE]; /* Hot counters. */
|
||||
|
@ -118,14 +118,13 @@ enum {
|
||||
#define CFRAME_SIZE 184
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#elif LJ_TARGET_MIPS
|
||||
/* NYI: Dummy definitions for now. */
|
||||
#define CFRAME_OFS_ERRF 0
|
||||
#define CFRAME_OFS_NRES 0
|
||||
#define CFRAME_OFS_PREV 0
|
||||
#define CFRAME_OFS_L 0
|
||||
#define CFRAME_OFS_PC 0
|
||||
#define CFRAME_OFS_MULTRES 0
|
||||
#define CFRAME_SIZE 256
|
||||
#define CFRAME_OFS_ERRF 124
|
||||
#define CFRAME_OFS_NRES 120
|
||||
#define CFRAME_OFS_PREV 116
|
||||
#define CFRAME_OFS_L 112
|
||||
#define CFRAME_OFS_PC 20
|
||||
#define CFRAME_OFS_MULTRES 16
|
||||
#define CFRAME_SIZE 112
|
||||
#define CFRAME_SHIFT_MULTRES 3
|
||||
#else
|
||||
#error "Missing CFRAME_* definitions for this architecture"
|
||||
|
@ -138,6 +138,8 @@ typedef uint32_t RegCost;
|
||||
#include "lj_target_arm.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "lj_target_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
#include "lj_target_mips.h"
|
||||
#else
|
||||
#error "Missing include for target CPU"
|
||||
#endif
|
||||
|
153
src/lj_target_mips.h
Normal file
153
src/lj_target_mips.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
** Definitions for MIPS CPUs.
|
||||
** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_TARGET_MIPS_H
|
||||
#define _LJ_TARGET_MIPS_H
|
||||
|
||||
/* -- Registers IDs ------------------------------------------------------- */
|
||||
|
||||
#define GPRDEF(_) \
|
||||
_(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
|
||||
_(R8) _(R9) _(R10) _(R11) _(R12) _(R13) _(R14) _(R15) \
|
||||
_(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \
|
||||
_(R24) _(R25) _(SYS1) _(SYS2) _(GP) _(SP) _(R30) _(RA)
|
||||
#define FPRDEF(_) \
|
||||
_(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
|
||||
_(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
|
||||
_(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
|
||||
_(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
|
||||
#define VRIDDEF(_)
|
||||
|
||||
#define RIDENUM(name) RID_##name,
|
||||
|
||||
enum {
|
||||
GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
|
||||
FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
|
||||
RID_MAX,
|
||||
RID_TMP = RID_RA,
|
||||
|
||||
/* Calling conventions. */
|
||||
RID_RET = RID_R2,
|
||||
#if LJ_LE
|
||||
RID_RETHI = RID_R3,
|
||||
RID_RETLO = RID_R2,
|
||||
#else
|
||||
RID_RETHI = RID_R2,
|
||||
RID_RETLO = RID_R3,
|
||||
#endif
|
||||
RID_FPRET = RID_F0,
|
||||
|
||||
/* These definitions must match with the *.dasc file(s): */
|
||||
RID_BASE = RID_R16, /* Interpreter BASE. */
|
||||
RID_LPC = RID_R18, /* Interpreter PC. */
|
||||
RID_DISPATCH = RID_R19, /* Interpreter DISPATCH table. */
|
||||
RID_LREG = RID_R20, /* Interpreter L. */
|
||||
RID_JGL = RID_R30, /* On-trace: global_State + 32768. */
|
||||
|
||||
/* Register ranges [min, max) and number of registers. */
|
||||
RID_MIN_GPR = RID_R0,
|
||||
RID_MAX_GPR = RID_RA+1,
|
||||
RID_MIN_FPR = RID_F0,
|
||||
RID_MAX_FPR = RID_F31+1,
|
||||
RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
|
||||
RID_NUM_FPR = (RID_MAX_FPR - RID_MIN_FPR)/2
|
||||
};
|
||||
|
||||
#define RID_NUM_KREF RID_NUM_GPR
|
||||
#define RID_MIN_KREF RID_R0
|
||||
|
||||
/* -- Register sets ------------------------------------------------------- */
|
||||
|
||||
/* Make use of all registers, except TMP, SP, SYS1, SYS2 and JGL. */
|
||||
#define RSET_FIXED \
|
||||
(RID2RSET(RID_TMP)|RID2RSET(RID_SP)|RID2RSET(RID_SYS1)|\
|
||||
RID2RSET(RID_SYS2)|RID2RSET(RID_JGL))
|
||||
#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
|
||||
#define RSET_FPR \
|
||||
(RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
|
||||
RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
|
||||
RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\
|
||||
RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30))
|
||||
#define RSET_ALL (RSET_GPR|RSET_FPR)
|
||||
#define RSET_INIT RSET_ALL
|
||||
|
||||
#define RSET_SCRATCH_GPR \
|
||||
(RSET_RANGE(RID_R1, RID_R15+1)|\
|
||||
RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_GP)|RID2RSET(RID_RA))
|
||||
#define RSET_SCRATCH_FPR \
|
||||
(RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
|
||||
RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
|
||||
RID2RSET(RID_F16)|RID2RSET(RID_F18))
|
||||
#define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
|
||||
#define REGARG_FIRSTGPR RID_R4
|
||||
#define REGARG_LASTGPR RID_R7
|
||||
#define REGARG_NUMGPR 4
|
||||
#define REGARG_FIRSTFPR RID_F12
|
||||
#define REGARG_LASTFPR RID_F14
|
||||
#define REGARG_NUMFPR 2
|
||||
|
||||
/* -- Spill slots --------------------------------------------------------- */
|
||||
|
||||
/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
|
||||
**
|
||||
** SPS_FIXED: Available fixed spill slots in interpreter frame.
|
||||
** This definition must match with the *.dasc file(s).
|
||||
**
|
||||
** SPS_FIRST: First spill slot for general use.
|
||||
*/
|
||||
#define SPS_FIXED 5
|
||||
#define SPS_FIRST 4
|
||||
|
||||
#define sps_scale(slot) (4 * (int32_t)(slot))
|
||||
#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
|
||||
|
||||
/* -- Exit state ---------------------------------------------------------- */
|
||||
|
||||
/* This definition must match with the *.dasc file(s). */
|
||||
typedef struct {
|
||||
lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
|
||||
int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
|
||||
int32_t spill[256]; /* Spill slots. */
|
||||
} ExitState;
|
||||
|
||||
/* Highest exit + 1 indicates stack check. */
|
||||
#define EXITSTATE_CHECKEXIT 1
|
||||
|
||||
#define EXITSTUB_SPACING 8
|
||||
#define EXITSTUBS_PER_GROUP 16
|
||||
|
||||
/* -- Instructions -------------------------------------------------------- */
|
||||
|
||||
/* Instruction fields. */
|
||||
#define MIPSF_S(r) ((r) << 21)
|
||||
#define MIPSF_T(r) ((r) << 16)
|
||||
#define MIPSF_D(r) ((r) << 11)
|
||||
#define MIPSF_R(r) ((r) << 21)
|
||||
#define MIPSF_H(r) ((r) << 16)
|
||||
#define MIPSF_G(r) ((r) << 11)
|
||||
#define MIPSF_F(r) ((r) << 6)
|
||||
#define MIPSF_A(n) ((n) << 6)
|
||||
#define MIPSF_M(n) ((n) << 11)
|
||||
|
||||
typedef enum MIPSIns {
|
||||
/* Integer instructions. */
|
||||
MIPSI_MOVE = 0x00000021,
|
||||
MIPSI_NOP = 0x00000000,
|
||||
|
||||
MIPSI_LI = 0x24000000,
|
||||
MIPSI_LU = 0x34000000,
|
||||
MIPSI_LUI = 0x3c000000,
|
||||
|
||||
MIPSI_ORI = 0x34000000,
|
||||
|
||||
MIPSI_B = 0x10000000,
|
||||
MIPSI_JR = 0x00000008,
|
||||
|
||||
/* Load/store instructions. */
|
||||
MIPSI_LW = 0x8c000000,
|
||||
MIPSI_SW = 0xac000000,
|
||||
} MIPSIns;
|
||||
|
||||
#endif
|
@ -10,7 +10,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "lj_obj.h"
|
||||
#if LJ_HASJIT
|
||||
#if LJ_HASJIT || LJ_TARGET_MIPS
|
||||
#include "lj_ir.h"
|
||||
#endif
|
||||
#include "lj_vm.h"
|
||||
@ -24,6 +24,29 @@ LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); }
|
||||
LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); }
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_MIPS
|
||||
double lj_vm_foldarith(double x, double y, int op)
|
||||
{
|
||||
switch (op) {
|
||||
case IR_ADD - IR_ADD: return x+y; break;
|
||||
case IR_SUB - IR_ADD: return x-y; break;
|
||||
case IR_MUL - IR_ADD: return x*y; break;
|
||||
case IR_DIV - IR_ADD: return x/y; break;
|
||||
case IR_MOD - IR_ADD: return x-lj_vm_floor(x/y)*y; break;
|
||||
case IR_POW - IR_ADD: return pow(x, y); break;
|
||||
case IR_NEG - IR_ADD: return -x; break;
|
||||
case IR_ABS - IR_ADD: return fabs(x); break;
|
||||
#if LJ_HASJIT
|
||||
case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
|
||||
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
|
||||
case IR_MIN - IR_ADD: return x > y ? y : x; break;
|
||||
case IR_MAX - IR_ADD: return x < y ? y : x; break;
|
||||
#endif
|
||||
default: return x;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LJ_HASJIT
|
||||
|
||||
#ifdef LUAJIT_NO_LOG2
|
||||
|
Loading…
Reference in New Issue
Block a user