From 5bed11e6b4c2bbf0cbec0f00efe998289236b217 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 23 Jan 2012 22:20:28 +0100 Subject: [PATCH] MIPS: Add interpreter. Enable MIPS build rules. --- src/Makefile | 5 +- src/Makefile.dep | 11 +- src/buildvm_asm.c | 8 +- src/buildvm_mips.dasc | 4114 +++++++++++++++++++++++ src/buildvm_mips.h | 7245 +++++++++++++++++++++++++++++++++++++++++ src/lib_base.c | 2 + src/lj_arch.h | 6 +- src/lj_ccall.c | 59 +- src/lj_ccall.h | 15 + src/lj_ccallback.c | 47 + src/lj_dispatch.c | 22 + src/lj_dispatch.h | 38 + src/lj_frame.h | 15 +- src/lj_target.h | 2 + src/lj_target_mips.h | 153 + src/lj_vmmath.c | 25 +- 16 files changed, 11743 insertions(+), 24 deletions(-) create mode 100644 src/buildvm_mips.dasc create mode 100644 src/buildvm_mips.h create mode 100644 src/lj_target_mips.h diff --git a/src/Makefile b/src/Makefile index 5a60612d..d4db8774 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 \ diff --git a/src/Makefile.dep b/src/Makefile.dep index add7508a..7a621242 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -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 \ diff --git a/src/buildvm_asm.c b/src/buildvm_asm.c index 236dd176..4ba60638 100644 --- a/src/buildvm_asm.c +++ b/src/buildvm_asm.c @@ -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; diff --git a/src/buildvm_mips.dasc b/src/buildvm_mips.dasc new file mode 100644 index 00000000..6b3103dd --- /dev/null +++ b/src/buildvm_mips.dasc @@ -0,0 +1,4114 @@ +|// Low-level VM code for MIPS CPUs. +|// Bytecode interpreter, fast functions and helper functions. +|// Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h +| +|.arch mips +|.section code_op, code_sub +| +|.actionlist build_actionlist +|.globals GLOB_ +|.globalnames globnames +|.externnames extnames +| +|// Note: The ragged indentation of the instructions is intentional. +|// The starting columns indicate data dependencies. +| +|//----------------------------------------------------------------------- +| +|// Fixed register assignments for the interpreter. +|// Don't use: r0 = 0, r26/r27 = reserved, r28 = gp, r29 = sp, r31 = ra +| +|// The following must be C callee-save (but BASE is often refetched). +|.define BASE, r16 // Base of current Lua stack frame. +|.define KBASE, r17 // Constants of current Lua function. +|.define PC, r18 // Next PC. +|.define DISPATCH, r19 // Opcode dispatch table. +|.define LREG, r20 // Register holding lua_State (also in SAVE_L). +|.define MULTRES, r21 // Size of multi-result: (nresults+1)*8. +|// NYI: r22 currently unused. +| +|.define JGL, r30 // On-trace: global_State + 32768. +| +|// Constants for type-comparisons, stores and conversions. C callee-save. +|.define TISNIL, r30 +|.define TOBIT, f30 // 2^52 + 2^51. +| +|// The following temporaries are not saved across C calls, except for RA. +|.define RA, r23 // Callee-save. +|.define RB, r8 +|.define RC, r9 +|.define RD, r10 +|.define INS, r11 +| +|.define AT, r1 // Assembler temporary. +|.define TMP0, r12 +|.define TMP1, r13 +|.define TMP2, r14 +|.define TMP3, r15 +| +|// Calling conventions. +|.define CFUNCADDR, r25 +|.define CARG1, r4 +|.define CARG2, r5 +|.define CARG3, r6 +|.define CARG4, r7 +| +|.define CRET1, r2 +|.define CRET2, r3 +| +|.define FARG1, f12 +|.define FARG2, f14 +| +|.define FRET1, f0 +|.define FRET2, f2 +| +|// Stack layout while in interpreter. Must match with lj_frame.h. +|.define CFRAME_SPACE, 112 // Delta for sp. +| +|.define SAVE_ERRF, 124(sp) // 32 bit C frame info. +|.define SAVE_NRES, 120(sp) +|.define SAVE_CFRAME, 116(sp) +|.define SAVE_L, 112(sp) +|//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by interpreter. +|.define SAVE_GPR_, 72 // .. 72+10*4: 32 bit GPR saves. +|.define SAVE_FPR_, 24 // .. 24+6*8: 64 bit FPR saves. +|.define SAVE_PC, 20(sp) +|.define ARG5, 16(sp) +|.define CSAVE_4, 12(sp) +|.define CSAVE_3, 8(sp) +|.define CSAVE_2, 4(sp) +|.define CSAVE_1, 0(sp) +|//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by callee. +| +|.define ARG5_OFS, 16 +|.define SAVE_MULTRES, ARG5 +| +|.macro saveregs +| addiu sp, sp, -CFRAME_SPACE +| sw ra, SAVE_GPR_+9*4(sp) +| sw r30, SAVE_GPR_+8*4(sp) +| sdc1 f30, SAVE_FPR_+5*8(sp) +| sw r23, SAVE_GPR_+7*4(sp) +| sw r22, SAVE_GPR_+6*4(sp) +| sdc1 f28, SAVE_FPR_+4*8(sp) +| sw r21, SAVE_GPR_+5*4(sp) +| sw r20, SAVE_GPR_+4*4(sp) +| sdc1 f26, SAVE_FPR_+3*8(sp) +| sw r19, SAVE_GPR_+3*4(sp) +| sw r18, SAVE_GPR_+2*4(sp) +| sdc1 f24, SAVE_FPR_+2*8(sp) +| sw r17, SAVE_GPR_+1*4(sp) +| sw r16, SAVE_GPR_+0*4(sp) +| sdc1 f22, SAVE_FPR_+1*8(sp) +| sdc1 f20, SAVE_FPR_+0*8(sp) +|.endmacro +| +|.macro restoreregs_ret +| lw ra, SAVE_GPR_+9*4(sp) +| lw r30, SAVE_GPR_+8*4(sp) +| ldc1 f30, SAVE_FPR_+5*8(sp) +| lw r23, SAVE_GPR_+7*4(sp) +| lw r22, SAVE_GPR_+6*4(sp) +| ldc1 f28, SAVE_FPR_+4*8(sp) +| lw r21, SAVE_GPR_+5*4(sp) +| lw r20, SAVE_GPR_+4*4(sp) +| ldc1 f26, SAVE_FPR_+3*8(sp) +| lw r19, SAVE_GPR_+3*4(sp) +| lw r18, SAVE_GPR_+2*4(sp) +| ldc1 f24, SAVE_FPR_+2*8(sp) +| lw r17, SAVE_GPR_+1*4(sp) +| lw r16, SAVE_GPR_+0*4(sp) +| ldc1 f22, SAVE_FPR_+1*8(sp) +| ldc1 f20, SAVE_FPR_+0*8(sp) +| jr ra +| addiu sp, sp, CFRAME_SPACE +|.endmacro +| +|// Type definitions. Some of these are only used for documentation. +|.type L, lua_State, LREG +|.type GL, global_State +|.type TVALUE, TValue +|.type GCOBJ, GCobj +|.type STR, GCstr +|.type TAB, GCtab +|.type LFUNC, GCfuncL +|.type CFUNC, GCfuncC +|.type PROTO, GCproto +|.type UPVAL, GCupval +|.type NODE, Node +|.type NARGS8, int +|.type TRACE, GCtrace +| +|//----------------------------------------------------------------------- +| +|// Trap for not-yet-implemented parts. +|.macro NYI; .long 0xf0f0f0f0; .endmacro +| +|// Macros to mark delay slots. +|.macro ., a; a; .endmacro +|.macro ., a,b; a,b; .endmacro +|.macro ., a,b,c; a,b,c; .endmacro +| +|//----------------------------------------------------------------------- +| +|// Endian-specific defines. +|.define FRAME_PC, LJ_ENDIAN_SELECT(-4,-8) +|.define FRAME_FUNC, LJ_ENDIAN_SELECT(-8,-4) +|.define HI, LJ_ENDIAN_SELECT(4,0) +|.define LO, LJ_ENDIAN_SELECT(0,4) +|.define OFS_RD, LJ_ENDIAN_SELECT(2,0) +|.define OFS_RA, LJ_ENDIAN_SELECT(1,2) +|.define OFS_OP, LJ_ENDIAN_SELECT(0,3) +| +|// Instruction decode. +|.macro decode_OP1, dst, ins; andi dst, ins, 0xff; .endmacro +|.macro decode_OP4a, dst, ins; andi dst, ins, 0xff; .endmacro +|.macro decode_OP4b, dst; sll dst, dst, 2; .endmacro +|.macro decode_RC4a, dst, ins; srl dst, ins, 14; .endmacro +|.macro decode_RC4b, dst; andi dst, dst, 0x3fc; .endmacro +|.macro decode_RD4b, dst; sll dst, dst, 2; .endmacro +|.macro decode_RA8a, dst, ins; srl dst, ins, 5; .endmacro +|.macro decode_RA8b, dst; andi dst, dst, 0x7f8; .endmacro +|.macro decode_RB8a, dst, ins; srl dst, ins, 21; .endmacro +|.macro decode_RB8b, dst; andi dst, dst, 0x7f8; .endmacro +|.macro decode_RD8a, dst, ins; srl dst, ins, 16; .endmacro +|.macro decode_RD8b, dst; sll dst, dst, 3; .endmacro +|.macro decode_RDtoRC8, dst, src; andi dst, src, 0x7f8; .endmacro +| +|// Instruction fetch. +|.macro ins_NEXT1 +| lw INS, 0(PC) +| addiu PC, PC, 4 +|.endmacro +|// Instruction decode+dispatch. +|.macro ins_NEXT2 +| decode_OP4a TMP1, INS +| decode_OP4b TMP1 +| addu TMP0, DISPATCH, TMP1 +| decode_RD8a RD, INS +| lw AT, 0(TMP0) +| decode_RA8a RA, INS +| decode_RD8b RD +| jr AT +| decode_RA8b RA +|.endmacro +|.macro ins_NEXT +| ins_NEXT1 +| ins_NEXT2 +|.endmacro +| +|// Instruction footer. +|.if 1 +| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use. +| .define ins_next, ins_NEXT +| .define ins_next_, ins_NEXT +| .define ins_next1, ins_NEXT1 +| .define ins_next2, ins_NEXT2 +|.else +| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch. +| // Affects only certain kinds of benchmarks (and only with -j off). +| .macro ins_next +| b ->ins_next +| .endmacro +| .macro ins_next1 +| .endmacro +| .macro ins_next2 +| b ->ins_next +| .endmacro +| .macro ins_next_ +| ->ins_next: +| ins_NEXT +| .endmacro +|.endif +| +|// Call decode and dispatch. +|.macro ins_callt +| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC +| lw PC, LFUNC:RB->pc +| lw INS, 0(PC) +| addiu PC, PC, 4 +| decode_OP4a TMP1, INS +| decode_RA8a RA, INS +| decode_OP4b TMP1 +| decode_RA8b RA +| addu TMP0, DISPATCH, TMP1 +| lw TMP0, 0(TMP0) +| jr TMP0 +| addu RA, RA, BASE +|.endmacro +| +|.macro ins_call +| // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, PC = caller PC +| sw PC, FRAME_PC(BASE) +| ins_callt +|.endmacro +| +|//----------------------------------------------------------------------- +| +|.macro branch_RD +| srl TMP0, RD, 1 +| lui AT, (-(BCBIAS_J*4 >> 16) & 65535) +| addu TMP0, TMP0, AT +| addu PC, PC, TMP0 +|.endmacro +| +|// Assumes DISPATCH is relative to GL. +#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field)) +#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field)) +#define GG_DISP2GOT (GG_OFS(got) - GG_OFS(dispatch)) +#define DISPATCH_GOT(name) (GG_DISP2GOT + 4*LJ_GOT_##name) +| +#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto)) +| +|.macro load_got, func +| lw CFUNCADDR, DISPATCH_GOT(func)(DISPATCH) +|.endmacro +|// Much faster. Sadly, there's no easy way to force the required code layout. +|// .macro call_intern, func; bal extern func; .endmacro +|.macro call_intern, func; jalr CFUNCADDR; .endmacro +|.macro call_extern; jalr CFUNCADDR; .endmacro +|.macro jmp_extern; jr CFUNCADDR; .endmacro +| +|.macro hotcheck, delta, target +|NYI +|.endmacro +| +|.macro hotloop +| hotcheck HOTCOUNT_LOOP, ->vm_hotloop +|.endmacro +| +|.macro hotcall +| hotcheck HOTCOUNT_CALL, ->vm_hotcall +|.endmacro +| +|// Set current VM state. Uses TMP0. +|.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro +|.macro st_vmstate; sw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro +| +|// Move table write barrier back. Overwrites mark and tmp. +|.macro barrierback, tab, mark, tmp, target +| lw tmp, DISPATCH_GL(gc.grayagain)(DISPATCH) +| andi mark, mark, ~LJ_GC_BLACK & 255 // black2gray(tab) +| sw tab, DISPATCH_GL(gc.grayagain)(DISPATCH) +| sb mark, tab->marked +| b target +|. sw tmp, tab->gclist +|.endmacro +| +|//----------------------------------------------------------------------- + +/* Generate subroutines used by opcodes and other parts of the VM. */ +/* The .code_sub section should be last to help static branch prediction. */ +static void build_subroutines(BuildCtx *ctx) +{ + |.code_sub + | + |//----------------------------------------------------------------------- + |//-- Return handling ---------------------------------------------------- + |//----------------------------------------------------------------------- + | + |->vm_returnp: + | // See vm_return. Also: TMP2 = previous base. + | andi AT, PC, FRAME_P + | beqz AT, ->cont_dispatch + |. li TMP1, LJ_TTRUE + | + | // Return from pcall or xpcall fast func. + | lw PC, FRAME_PC(TMP2) // Fetch PC of previous frame. + | move BASE, TMP2 // Restore caller base. + | // Prepending may overwrite the pcall frame, so do it at the end. + | sw TMP1, FRAME_PC(RA) // Prepend true to results. + | addiu RA, RA, -8 + | + |->vm_returnc: + | andi TMP0, PC, FRAME_TYPE + | addiu RD, RD, 8 // RD = (nresults+1)*8. + | beqz TMP0, ->BC_RET_Z // Handle regular return to Lua. + |. move MULTRES, RD + | + |->vm_return: + | // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return + | // TMP0 = PC & FRAME_TYPE + | li TMP2, -8 + | xori AT, TMP0, FRAME_C + | and TMP2, PC, TMP2 + | bnez AT, ->vm_returnp + | subu TMP2, BASE, TMP2 // TMP2 = previous base. + | + | addiu TMP1, RD, -8 + | sw TMP2, L->base + | li_vmstate C + | lw TMP2, SAVE_NRES + | addiu BASE, BASE, -8 + | st_vmstate + | beqz TMP1, >2 + |. sll TMP2, TMP2, 3 + |1: + | addiu TMP1, TMP1, -8 + | ldc1 f0, 0(RA) + | addiu RA, RA, 8 + | sdc1 f0, 0(BASE) + | bnez TMP1, <1 + |. addiu BASE, BASE, 8 + | + |2: + | bne TMP2, RD, >6 + |3: + |. sw BASE, L->top // Store new top. + | + |->vm_leave_cp: + | lw TMP0, SAVE_CFRAME // Restore previous C frame. + | move CRET1, r0 // Ok return status for vm_pcall. + | sw TMP0, L->cframe + | + |->vm_leave_unw: + | restoreregs_ret + | + |6: + | lw TMP1, L->maxstack + | slt AT, TMP2, RD + | bnez AT, >7 // Less results wanted? + | // More results wanted. Check stack size and fill up results with nil. + |. slt AT, BASE, TMP1 + | beqz AT, >8 + |. nop + | sw TISNIL, HI(BASE) + | addiu RD, RD, 8 + | b <2 + |. addiu BASE, BASE, 8 + | + |7: // Less results wanted. + | subu TMP0, RD, TMP2 + | subu TMP0, BASE, TMP0 // Either keep top or shrink it. + | b <3 + |. movn BASE, TMP0, TMP2 // LUA_MULTRET+1 case? + | + |8: // Corner case: need to grow stack for filling up results. + | // This can happen if: + | // - A C function grows the stack (a lot). + | // - The GC shrinks the stack in between. + | // - A return back from a lua_call() with (high) nresults adjustment. + | load_got lj_state_growstack + | move MULTRES, RD + | move CARG2, TMP2 + | call_intern lj_state_growstack // (lua_State *L, int n) + |. move CARG1, L + | lw TMP2, SAVE_NRES + | lw BASE, L->top // Need the (realloced) L->top in BASE. + | move RD, MULTRES + | b <2 + |. sll TMP2, TMP2, 3 + | + |->vm_unwind_c: // Unwind C stack, return from vm_pcall. + | // (void *cframe, int errcode) + | move sp, CARG1 + | move CRET1, CARG2 + |->vm_unwind_c_eh: // Landing pad for external unwinder. + | lw L, SAVE_L + | li TMP0, ~LJ_VMST_C + | lw GL:TMP1, L->glref + | b ->vm_leave_unw + |. sw TMP0, GL:TMP1->vmstate + | + |->vm_unwind_ff: // Unwind C stack, return from ff pcall. + | // (void *cframe) + | li AT, -4 + | and sp, CARG1, AT + |->vm_unwind_ff_eh: // Landing pad for external unwinder. + | lw L, SAVE_L + | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | li TISNIL, LJ_TNIL + | lw BASE, L->base + | lw DISPATCH, L->glref // Setup pointer to dispatch table. + | mtc1 TMP3, TOBIT + | li TMP1, LJ_TFALSE + | li_vmstate INTERP + | lw PC, FRAME_PC(BASE) // Fetch PC of previous frame. + | cvt.d.s TOBIT, TOBIT + | addiu RA, BASE, -8 // Results start at BASE-8. + | addiu DISPATCH, DISPATCH, GG_G2DISP + | sw TMP1, HI(RA) // Prepend false to error message. + | st_vmstate + | b ->vm_returnc + |. li RD, 16 // 2 results: false + error message. + | + |//----------------------------------------------------------------------- + |//-- Grow stack for calls ----------------------------------------------- + |//----------------------------------------------------------------------- + | + |->vm_growstack_c: // Grow stack for C function. + | b >2 + |. li CARG2, LUA_MINSTACK + | + |->vm_growstack_l: // Grow stack for Lua function. + | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC + | addu RC, BASE, RC + | subu RA, RA, BASE + | sw BASE, L->base + | addiu PC, PC, 4 // Must point after first instruction. + | sw RC, L->top + | srl CARG2, RA, 3 + |2: + | // L->base = new base, L->top = top + | load_got lj_state_growstack + | sw PC, SAVE_PC + | call_intern lj_state_growstack // (lua_State *L, int n) + |. move CARG1, L + | lw BASE, L->base + | lw RC, L->top + | lw LFUNC:RB, FRAME_FUNC(BASE) + | subu RC, RC, BASE + | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC + | ins_callt // Just retry the call. + | + |//----------------------------------------------------------------------- + |//-- Entry points into the assembler VM --------------------------------- + |//----------------------------------------------------------------------- + | + |->vm_resume: // Setup C frame and resume thread. + | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0) + | saveregs + | move L, CARG1 + | lw DISPATCH, L->glref // Setup pointer to dispatch table. + | move BASE, CARG2 + | lbu TMP1, L->status + | sw L, SAVE_L + | li PC, FRAME_CP + | addiu TMP0, sp, CFRAME_RESUME + | addiu DISPATCH, DISPATCH, GG_G2DISP + | sw r0, SAVE_NRES + | sw r0, SAVE_ERRF + | sw TMP0, L->cframe + | sw r0, SAVE_CFRAME + | beqz TMP1, >3 + |. sw CARG1, SAVE_PC // Any value outside of bytecode is ok. + | + | // Resume after yield (like a return). + | move RA, BASE + | lw BASE, L->base + | lw TMP1, L->top + | lw PC, FRAME_PC(BASE) + | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | subu RD, TMP1, BASE + | mtc1 TMP3, TOBIT + | sb r0, L->status + | cvt.d.s TOBIT, TOBIT + | li_vmstate INTERP + | addiu RD, RD, 8 + | st_vmstate + | move MULTRES, RD + | andi TMP0, PC, FRAME_TYPE + | beqz TMP0, ->BC_RET_Z + |. li TISNIL, LJ_TNIL + | b ->vm_return + |. nop + | + |->vm_pcall: // Setup protected C frame and enter VM. + | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef) + | saveregs + | sw CARG4, SAVE_ERRF + | b >1 + |. li PC, FRAME_CP + | + |->vm_call: // Setup C frame and enter VM. + | // (lua_State *L, TValue *base, int nres1) + | saveregs + | li PC, FRAME_C + | + |1: // Entry point for vm_pcall above (PC = ftype). + | lw TMP1, L:CARG1->cframe + | sw CARG3, SAVE_NRES + | move L, CARG1 + | sw CARG1, SAVE_L + | move BASE, CARG2 + | sw sp, L->cframe // Add our C frame to cframe chain. + | lw DISPATCH, L->glref // Setup pointer to dispatch table. + | sw CARG1, SAVE_PC // Any value outside of bytecode is ok. + | sw TMP1, SAVE_CFRAME + | addiu DISPATCH, DISPATCH, GG_G2DISP + | + |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). + | lw TMP2, L->base // TMP2 = old base (used in vmeta_call). + | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | lw TMP1, L->top + | mtc1 TMP3, TOBIT + | addu PC, PC, BASE + | subu NARGS8:RC, TMP1, BASE + | subu PC, PC, TMP2 // PC = frame delta + frame type + | cvt.d.s TOBIT, TOBIT + | li_vmstate INTERP + | li TISNIL, LJ_TNIL + | st_vmstate + | + |->vm_call_dispatch: + | // TMP2 = old base, BASE = new base, RC = nargs*8, PC = caller PC + | lw TMP0, FRAME_PC(BASE) + | li AT, LJ_TFUNC + | bne TMP0, AT, ->vmeta_call + |. lw LFUNC:RB, FRAME_FUNC(BASE) + | + |->vm_call_dispatch_f: + | ins_call + | // BASE = new base, RB = func, RC = nargs*8, PC = caller PC + | + |->vm_cpcall: // Setup protected C frame, call C. + | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp) + | saveregs + | move L, CARG1 + | lw TMP0, L:CARG1->stack + | sw CARG1, SAVE_L + | lw TMP1, L->top + | sw CARG1, SAVE_PC // Any value outside of bytecode is ok. + | subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top). + | lw TMP1, L->cframe + | sw sp, L->cframe // Add our C frame to cframe chain. + | sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame. + | sw r0, SAVE_ERRF // No error function. + | move CFUNCADDR, CARG4 + | jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud) + |. sw TMP1, SAVE_CFRAME + | move BASE, CRET1 + | lw DISPATCH, L->glref // Setup pointer to dispatch table. + | li PC, FRAME_CP + | bnez CRET1, <3 // Else continue with the call. + |. addiu DISPATCH, DISPATCH, GG_G2DISP + | b ->vm_leave_cp // No base? Just remove C frame. + |. nop + | + |//----------------------------------------------------------------------- + |//-- Metamethod handling ------------------------------------------------ + |//----------------------------------------------------------------------- + | + |// The lj_meta_* functions (except for lj_meta_cat) don't reallocate the + |// stack, so BASE doesn't need to be reloaded across these calls. + | + |//-- Continuation dispatch ---------------------------------------------- + | + |->cont_dispatch: + | // BASE = meta base, RA = resultptr, RD = (nresults+1)*8 + | lw TMP0, -16+LO(BASE) // Continuation. + | move RB, BASE + | move BASE, TMP2 // Restore caller BASE. + | lw LFUNC:TMP1, FRAME_FUNC(TMP2) +#if LJ_HASFFI + | sltiu AT, TMP0, 2 +#endif + | lw PC, -16+HI(RB) // Restore PC from [cont|PC]. + | addu TMP2, RA, RD + | lw TMP1, LFUNC:TMP1->pc +#if LJ_HASFFI + | bnez AT, >1 +#endif + |. sw TISNIL, -8+HI(TMP2) // Ensure one valid arg. + | // BASE = base, RA = resultptr, RB = meta base + | jr TMP0 // Jump to continuation. + |. lw KBASE, PC2PROTO(k)(TMP1) + | +#if LJ_HASFFI + |1: + | bnez TMP0, ->cont_ffi_callback // cont = 1: return from FFI callback. + | // cont = 0: tailcall from C function. + |. addiu TMP1, RB, -16 + | b ->vm_call_tail + |. subu RC, TMP1, BASE +#endif + | + |->cont_cat: // RA = resultptr, RB = meta base + | lw INS, -4(PC) + | addiu CARG2, RB, -16 + | ldc1 f0, 0(RA) + | decode_RB8a MULTRES, INS + | decode_RA8a RA, INS + | decode_RB8b MULTRES + | decode_RA8b RA + | addu TMP1, BASE, MULTRES + | sw BASE, L->base + | subu CARG3, CARG2, TMP1 + | bne TMP1, CARG2, ->BC_CAT_Z + |. sdc1 f0, 0(CARG2) + | addu RA, BASE, RA + | b ->cont_nop + |. sdc1 f0, 0(RA) + | + |//-- Table indexing metamethods ----------------------------------------- + | + |->vmeta_tgets1: + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | li TMP0, LJ_TSTR + | sw STR:RC, LO(CARG3) + | b >1 + |. sw TMP0, HI(CARG3) + | + |->vmeta_tgets: + | addiu CARG2, DISPATCH, DISPATCH_GL(tmptv) + | li TMP0, LJ_TTAB + | sw TAB:RB, LO(CARG2) + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv2) + | sw TMP0, HI(CARG2) + | li TMP1, LJ_TSTR + | sw STR:RC, LO(CARG3) + | b >1 + |. sw TMP1, HI(CARG3) + | + |->vmeta_tgetb: // TMP0 = index + | mtc1 TMP0, f0 + | cvt.d.w f0, f0 + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | sdc1 f0, 0(CARG3) + | + |->vmeta_tgetv: + |1: + | load_got lj_meta_tget + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_meta_tget // (lua_State *L, TValue *o, TValue *k) + |. move CARG1, L + | // Returns TValue * (finished) or NULL (metamethod). + | beqz CRET1, >3 + |. addiu TMP1, BASE, -FRAME_CONT + | ldc1 f0, 0(CRET1) + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + | + |3: // Call __index metamethod. + | // BASE = base, L->top = new base, stack = cont/func/t/k + | lw BASE, L->top + | sw PC, -16+HI(BASE) // [cont|PC] + | subu PC, BASE, TMP1 + | lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. + | b ->vm_call_dispatch_f + |. li NARGS8:RC, 16 // 2 args for func(t, k). + | + |//----------------------------------------------------------------------- + | + |->vmeta_tsets1: + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | li TMP0, LJ_TSTR + | sw STR:RC, LO(CARG3) + | b >1 + |. sw TMP0, HI(CARG3) + | + |->vmeta_tsets: + | addiu CARG2, DISPATCH, DISPATCH_GL(tmptv) + | li TMP0, LJ_TTAB + | sw TAB:RB, LO(CARG2) + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv2) + | sw TMP0, HI(CARG2) + | li TMP1, LJ_TSTR + | sw STR:RC, LO(CARG3) + | b >1 + |. sw TMP1, HI(CARG3) + | + |->vmeta_tsetb: // TMP0 = index + | mtc1 TMP0, f0 + | cvt.d.w f0, f0 + | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | sdc1 f0, 0(CARG3) + | + |->vmeta_tsetv: + |1: + | load_got lj_meta_tset + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) + |. move CARG1, L + | // Returns TValue * (finished) or NULL (metamethod). + | beqz CRET1, >3 + |. ldc1 f0, 0(RA) + | // NOBARRIER: lj_meta_tset ensures the table is not black. + | ins_next1 + | sdc1 f0, 0(CRET1) + | ins_next2 + | + |3: // Call __newindex metamethod. + | // BASE = base, L->top = new base, stack = cont/func/t/k/(v) + | addiu TMP1, BASE, -FRAME_CONT + | lw BASE, L->top + | sw PC, -16+HI(BASE) // [cont|PC] + | subu PC, BASE, TMP1 + | lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. + | sdc1 f0, 16(BASE) // Copy value to third argument. + | b ->vm_call_dispatch_f + |. li NARGS8:RC, 24 // 3 args for func(t, k, v) + | + |//-- Comparison metamethods --------------------------------------------- + | + |->vmeta_comp: + | // CARG2, CARG3 are already set by BC_ISLT/BC_ISGE/BC_ISLE/BC_ISGT. + | load_got lj_meta_comp + | addiu PC, PC, -4 + | sw BASE, L->base + | sw PC, SAVE_PC + | decode_OP1 CARG4, INS + | call_intern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op) + |. move CARG1, L + | // Returns 0/1 or TValue * (metamethod). + |3: + | sltiu AT, CRET1, 2 + | beqz AT, ->vmeta_binop + | negu TMP2, CRET1 + |4: + | lhu RD, OFS_RD(PC) + | addiu PC, PC, 4 + | lui TMP1, (-(BCBIAS_J*4 >> 16) & 65535) + | sll RD, RD, 2 + | addu RD, RD, TMP1 + | and RD, RD, TMP2 + | addu PC, PC, RD + |->cont_nop: + | ins_next + | + |->cont_ra: // RA = resultptr + | lbu TMP1, -4+OFS_RA(PC) + | ldc1 f0, 0(RA) + | sll TMP1, TMP1, 3 + | addu TMP1, BASE, TMP1 + | b ->cont_nop + |. sdc1 f0, 0(TMP1) + | + |->cont_condt: // RA = resultptr + | lw TMP0, HI(RA) + | sltiu AT, TMP0, LJ_TISTRUECOND + | b <4 + |. negu TMP2, AT // Branch if result is true. + | + |->cont_condf: // RA = resultptr + | lw TMP0, HI(RA) + | sltiu AT, TMP0, LJ_TISTRUECOND + | b <4 + |. addiu TMP2, AT, -1 // Branch if result is false. + | + |->vmeta_equal: + | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV. + | load_got lj_meta_equal + | addiu PC, PC, -4 + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne) + |. move CARG1, L + | // Returns 0/1 or TValue * (metamethod). + | b <3 + |. nop + | + |->vmeta_equal_cd: +#if LJ_HASFFI + | load_got lj_meta_equal_cd + | move CARG2, INS + | addiu PC, PC, -4 + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_meta_equal_cd // (lua_State *L, BCIns op) + |. move CARG1, L + | // Returns 0/1 or TValue * (metamethod). + | b <3 + |. nop +#endif + | + |//-- Arithmetic metamethods --------------------------------------------- + | + |->vmeta_unm: + | move CARG4, CARG3 + | + |->vmeta_arith: + | load_got lj_meta_arith + | decode_OP1 TMP0, INS + | sw BASE, L->base + | sw PC, SAVE_PC + | move CARG2, RA + | sw TMP0, ARG5 + | call_intern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op) + |. move CARG1, L + | // Returns NULL (finished) or TValue * (metamethod). + | beqz CRET1, ->cont_nop + |. nop + | + | // Call metamethod for binary op. + |->vmeta_binop: + | // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2 + | subu TMP1, CRET1, BASE + | sw PC, -16+HI(CRET1) // [cont|PC] + | move TMP2, BASE + | addiu PC, TMP1, FRAME_CONT + | move BASE, CRET1 + | b ->vm_call_dispatch + |. li NARGS8:RC, 16 // 2 args for func(o1, o2). + | + |->vmeta_len: + | // CARG2 already set by BC_LEN. +#ifdef LUAJIT_ENABLE_LUA52COMPAT + | move MULTRES, CARG1 +#endif + | load_got lj_meta_len + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_meta_len // (lua_State *L, TValue *o) + |. move CARG1, L + | // Returns NULL (retry) or TValue * (metamethod base). +#ifdef LUAJIT_ENABLE_LUA52COMPAT + | bnez CRET1, ->vmeta_binop // Binop call for compatibility. + |. nop + | b ->BC_LEN_Z + |. move CARG1, MULTRES +#else + | b ->vmeta_binop // Binop call for compatibility. + |. nop +#endif + | + |//-- Call metamethod ---------------------------------------------------- + | + |->vmeta_call: // Resolve and call __call metamethod. + | // TMP2 = old base, BASE = new base, RC = nargs*8 + | load_got lj_meta_call + | sw TMP2, L->base // This is the callers base! + | addiu CARG2, BASE, -8 + | sw PC, SAVE_PC + | addu CARG3, BASE, RC + | move MULTRES, NARGS8:RC + | call_intern lj_meta_call // (lua_State *L, TValue *func, TValue *top) + |. move CARG1, L + | lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. + | addiu NARGS8:RC, MULTRES, 8 // Got one more argument now. + | ins_call + | + |->vmeta_callt: // Resolve __call for BC_CALLT. + | // BASE = old base, RA = new base, RC = nargs*8 + | load_got lj_meta_call + | sw BASE, L->base + | addiu CARG2, RA, -8 + | sw PC, SAVE_PC + | addu CARG3, RA, RC + | move MULTRES, NARGS8:RC + | call_intern lj_meta_call // (lua_State *L, TValue *func, TValue *top) + |. move CARG1, L + | lw TMP1, FRAME_PC(BASE) + | lw LFUNC:RB, FRAME_FUNC(RA) // Guaranteed to be a function here. + | b ->BC_CALLT_Z + |. addiu NARGS8:RC, MULTRES, 8 // Got one more argument now. + | + |//-- Argument coercion for 'for' statement ------------------------------ + | + |->vmeta_for: + | load_got lj_meta_for + | sw BASE, L->base + | move CARG2, RA + | sw PC, SAVE_PC + | move MULTRES, INS + | call_intern lj_meta_for // (lua_State *L, TValue *base) + |. move CARG1, L +#if LJ_HASJIT + | decode_OP1 TMP0, MULTRES + | li AT, BC_JFORI +#endif + | decode_RA8a RA, MULTRES + | decode_RD8a RD, MULTRES + | decode_RA8b RA +#if LJ_HASJIT + | beq TMP0, AT, =>BC_JFORI + |. decode_RD8b RD + | b =>BC_FORI + |. nop +#else + | b =>BC_FORI + |. decode_RD8b RD +#endif + | + |//----------------------------------------------------------------------- + |//-- Fast functions ----------------------------------------------------- + |//----------------------------------------------------------------------- + | + |.macro .ffunc, name + |->ff_ .. name: + |.endmacro + | + |.macro .ffunc_1, name + |->ff_ .. name: + | beqz NARGS8:RC, ->fff_fallback + |. lw CARG3, HI(BASE) + | lw CARG1, LO(BASE) + |.endmacro + | + |.macro .ffunc_2, name + |->ff_ .. name: + | sltiu AT, NARGS8:RC, 16 + | lw CARG3, HI(BASE) + | bnez AT, ->fff_fallback + |. lw CARG4, 8+HI(BASE) + | lw CARG1, LO(BASE) + | lw CARG2, 8+LO(BASE) + |.endmacro + | + |.macro .ffunc_n, name // Caveat: has delay slot! + |->ff_ .. name: + | lw CARG3, HI(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. ldc1 FARG1, 0(BASE) + | sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |.endmacro + | + |.macro .ffunc_nn, name // Caveat: has delay slot! + |->ff_ .. name: + | sltiu AT, NARGS8:RC, 16 + | lw CARG3, HI(BASE) + | bnez AT, ->fff_fallback + |. lw CARG4, 8+HI(BASE) + | ldc1 FARG1, 0(BASE) + | ldc1 FARG2, 8(BASE) + | sltiu TMP0, CARG3, LJ_TISNUM + | sltiu TMP1, CARG4, LJ_TISNUM + | and TMP0, TMP0, TMP1 + | beqz TMP0, ->fff_fallback + |.endmacro + | + |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1 and has delay slot! + |.macro ffgccheck + | lw TMP0, DISPATCH_GL(gc.total)(DISPATCH) + | lw TMP1, DISPATCH_GL(gc.threshold)(DISPATCH) + | subu AT, TMP0, TMP1 + | bgezal AT, ->fff_gcstep + |.endmacro + | + |//-- Base library: checks ----------------------------------------------- + | + |.ffunc_1 assert + | sltiu AT, CARG3, LJ_TISTRUECOND + | beqz AT, ->fff_fallback + |. addiu RA, BASE, -8 + | lw PC, FRAME_PC(BASE) + | addiu RD, NARGS8:RC, 8 // Compute (nresults+1)*8. + | addu TMP2, RA, NARGS8:RC + | sw CARG3, HI(RA) + | addiu TMP1, BASE, 8 + | beq BASE, TMP2, ->fff_res // Done if exactly 1 argument. + |. sw CARG1, LO(RA) + |1: + | ldc1 f0, 0(TMP1) + | sdc1 f0, -8(TMP1) + | bne TMP1, TMP2, <1 + |. addiu TMP1, TMP1, 8 + | b ->fff_res + |. nop + | + |.ffunc type + | lw CARG3, HI(BASE) + | li TMP1, LJ_TISNUM + | beqz NARGS8:RC, ->fff_fallback + |. sltiu TMP0, CARG3, LJ_TISNUM + | movz TMP1, CARG3, TMP0 + | not TMP1, TMP1 + | sll TMP1, TMP1, 3 + | addu TMP1, CFUNC:RB, TMP1 + | b ->fff_resn + |. ldc1 FRET1, CFUNC:TMP1->upvalue + | + |//-- Base library: getters and setters --------------------------------- + | + |.ffunc_1 getmetatable + | li AT, LJ_TTAB + | bne CARG3, AT, >6 + |. li AT, LJ_TUDATA + |1: // Field metatable must be at same offset for GCtab and GCudata! + | lw TAB:CARG1, TAB:CARG1->metatable + |2: + | lw STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH) + | beqz TAB:CARG1, ->fff_restv + |. li CARG3, LJ_TNIL + | lw TMP0, TAB:CARG1->hmask + | li CARG3, LJ_TTAB // Use metatable as default result. + | lw TMP1, STR:RC->hash + | lw NODE:TMP2, TAB:CARG1->node + | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask + | sll TMP0, TMP1, 5 + | sll TMP1, TMP1, 3 + | subu TMP1, TMP0, TMP1 + | addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) + | li AT, LJ_TSTR + |3: // Rearranged logic, because we expect _not_ to find the key. + | lw CARG4, offsetof(Node, key)+HI(NODE:TMP2) + | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) + | lw NODE:TMP3, NODE:TMP2->next + | bne CARG4, AT, >4 + |. lw CARG2, offsetof(Node, val)+HI(NODE:TMP2) + | beq TMP0, STR:RC, >5 + |. lw TMP1, offsetof(Node, val)+LO(NODE:TMP2) + |4: + | beqz NODE:TMP3, ->fff_restv // Not found, keep default result. + |. move NODE:TMP2, NODE:TMP3 + | b <3 + |. nop + |5: + | beq CARG2, TISNIL, ->fff_restv // Ditto for nil value. + |. nop + | move CARG3, CARG2 // Return value of mt.__metatable. + | b ->fff_restv + |. move CARG1, TMP1 + | + |6: + | beq CARG3, AT, <1 + |. sltiu TMP0, CARG3, LJ_TISNUM + | li TMP1, LJ_TISNUM + | movz TMP1, CARG3, TMP0 + | not TMP1, TMP1 + | sll TMP1, TMP1, 2 + | addu TMP1, DISPATCH, TMP1 + | b <2 + |. lw TAB:CARG1, DISPATCH_GL(gcroot[GCROOT_BASEMT])(TMP1) + | + |.ffunc_2 setmetatable + | // Fast path: no mt for table yet and not clearing the mt. + | li AT, LJ_TTAB + | bne CARG3, AT, ->fff_fallback + |. addiu CARG4, CARG4, -LJ_TTAB + | lw TAB:TMP1, TAB:CARG1->metatable + | lbu TMP3, TAB:CARG1->marked + | or AT, CARG4, TAB:TMP1 + | bnez AT, ->fff_fallback + |. andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | beqz AT, ->fff_restv + |. sw TAB:CARG2, TAB:CARG1->metatable + | barrierback TAB:CARG1, TMP3, TMP0, ->fff_restv + | + |.ffunc rawget + | lw CARG4, HI(BASE) + | sltiu AT, NARGS8:RC, 16 + | lw TAB:CARG2, LO(BASE) + | load_got lj_tab_get + | addiu CARG4, CARG4, -LJ_TTAB + | or AT, AT, CARG4 + | bnez AT, ->fff_fallback + | addiu CARG3, BASE, 8 + | call_intern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key) + |. move CARG1, L + | // Returns cTValue *. + | b ->fff_resn + |. ldc1 FRET1, 0(CRET1) + | + |//-- Base library: conversions ------------------------------------------ + | + |.ffunc tonumber + | // Only handles the number case inline (without a base argument). + | lw CARG1, HI(BASE) + | xori AT, NARGS8:RC, 8 + | sltiu CARG1, CARG1, LJ_TISNUM + | movn CARG1, r0, AT + | beqz CARG1, ->fff_fallback // Exactly one number argument. + |. ldc1 FRET1, 0(BASE) + | b ->fff_resn + |. nop + | + |.ffunc_1 tostring + | // Only handles the string or number case inline. + | li AT, LJ_TSTR + | // A __tostring method in the string base metatable is ignored. + | beq CARG3, AT, ->fff_restv // String key? + | // Handle numbers inline, unless a number base metatable is present. + |. lw TMP1, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH) + | sltiu TMP0, CARG3, LJ_TISNUM + | sltiu TMP1, TMP1, 1 + | and TMP0, TMP0, TMP1 + | beqz TMP0, ->fff_fallback + |. sw BASE, L->base // Add frame since C call can throw. + | ffgccheck + |. sw PC, SAVE_PC // Redundant (but a defined value). + | load_got lj_str_fromnum + | move CARG1, L + | call_intern lj_str_fromnum // (lua_State *L, lua_Number *np) + |. move CARG2, BASE + | // Returns GCstr *. + | li CARG3, LJ_TSTR + | b ->fff_restv + |. move CARG1, CRET1 + | + |//-- Base library: iterators ------------------------------------------- + | + |.ffunc next + | lw CARG1, HI(BASE) + | lw TAB:CARG2, LO(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. addu TMP2, BASE, NARGS8:RC + | li AT, LJ_TTAB + | sw TISNIL, HI(TMP2) // Set missing 2nd arg to nil. + | bne CARG1, AT, ->fff_fallback + |. lw PC, FRAME_PC(BASE) + | load_got lj_tab_next + | sw BASE, L->base // Add frame since C call can throw. + | sw BASE, L->top // Dummy frame length is ok. + | addiu CARG3, BASE, 8 + | sw PC, SAVE_PC + | call_intern lj_tab_next // (lua_State *L, GCtab *t, TValue *key) + |. move CARG1, L + | // Returns 0 at end of traversal. + | beqz CRET1, ->fff_restv // End of traversal: return nil. + |. li CARG3, LJ_TNIL + | ldc1 f0, 8(BASE) // Copy key and value to results. + | addiu RA, BASE, -8 + | ldc1 f2, 16(BASE) + | li RD, (2+1)*8 + | sdc1 f0, 0(RA) + | b ->fff_res + |. sdc1 f2, 8(RA) + | + |.ffunc_1 pairs + | li AT, LJ_TTAB + | bne CARG3, AT, ->fff_fallback + |. lw PC, FRAME_PC(BASE) +#ifdef LUAJIT_ENABLE_LUA52COMPAT + | lw TAB:TMP2, TAB:CARG1->metatable + | ldc1 f0, CFUNC:RB->upvalue[0] + | bnez TAB:TMP2, ->fff_fallback +#else + | ldc1 f0, CFUNC:RB->upvalue[0] +#endif + |. addiu RA, BASE, -8 + | sw TISNIL, 8+HI(BASE) + | li RD, (3+1)*8 + | b ->fff_res + |. sdc1 f0, 0(RA) + | + |.ffunc ipairs_aux + | sltiu AT, NARGS8:RC, 16 + | lw CARG3, HI(BASE) + | lw TAB:CARG1, LO(BASE) + | lw CARG4, 8+HI(BASE) + | bnez AT, ->fff_fallback + |. ldc1 FARG2, 8(BASE) + | addiu CARG3, CARG3, -LJ_TTAB + | sltiu AT, CARG4, LJ_TISNUM + | li TMP0, 1 + | movn AT, r0, CARG3 + | mtc1 TMP0, FARG1 + | beqz AT, ->fff_fallback + |. lw PC, FRAME_PC(BASE) + | cvt.w.d FRET1, FARG2 + | cvt.d.w FARG1, FARG1 + | lw TMP0, TAB:CARG1->asize + | lw TMP1, TAB:CARG1->array + | mfc1 TMP2, FRET1 + | addiu RA, BASE, -8 + | add.d FARG2, FARG2, FARG1 + | addiu TMP2, TMP2, 1 + | sltu AT, TMP2, TMP0 + | sll TMP3, TMP2, 3 + | addu TMP3, TMP1, TMP3 + | beqz AT, >2 // Not in array part? + |. sdc1 FARG2, 0(RA) + | lw TMP2, HI(TMP3) + | ldc1 f0, 0(TMP3) + |1: + | beq TMP2, TISNIL, ->fff_res // End of iteration, return 0 results. + |. li RD, (0+1)*8 + | li RD, (2+1)*8 + | b ->fff_res + |. sdc1 f0, 8(RA) + |2: // Check for empty hash part first. Otherwise call C function. + | lw TMP0, TAB:CARG1->hmask + | load_got lj_tab_getinth + | beqz TMP0, ->fff_res + |. li RD, (0+1)*8 + | call_intern lj_tab_getinth // (GCtab *t, int32_t key) + |. move CARG2, TMP2 + | // Returns cTValue * or NULL. + | beqz CRET1, ->fff_res + |. li RD, (0+1)*8 + | lw TMP2, HI(CRET1) + | b <1 + |. ldc1 f0, 0(CRET1) + | + |.ffunc_1 ipairs + | li AT, LJ_TTAB + | bne CARG3, AT, ->fff_fallback + |. lw PC, FRAME_PC(BASE) +#ifdef LUAJIT_ENABLE_LUA52COMPAT + | lw TAB:TMP2, TAB:CARG1->metatable + | ldc1 f0, CFUNC:RB->upvalue[0] + | bnez TAB:TMP2, ->fff_fallback +#else + | ldc1 f0, CFUNC:RB->upvalue[0] +#endif + |. addiu RA, BASE, -8 + | sw r0, 8+HI(BASE) + | sw r0, 8+LO(BASE) + | li RD, (3+1)*8 + | b ->fff_res + |. sdc1 f0, 0(RA) + | + |//-- Base library: catch errors ---------------------------------------- + | + |.ffunc pcall + | lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) + | beqz NARGS8:RC, ->fff_fallback + | move TMP2, BASE + | addiu BASE, BASE, 8 + | // Remember active hook before pcall. + | srl TMP3, TMP3, HOOK_ACTIVE_SHIFT + | andi TMP3, TMP3, 1 + | addiu PC, TMP3, 8+FRAME_PCALL + | b ->vm_call_dispatch + |. addiu NARGS8:RC, NARGS8:RC, -8 + | + |.ffunc xpcall + | sltiu AT, NARGS8:RC, 16 + | lw CARG4, 8+HI(BASE) + | bnez AT, ->fff_fallback + |. ldc1 FARG2, 8(BASE) + | ldc1 FARG1, 0(BASE) + | lbu TMP1, DISPATCH_GL(hookmask)(DISPATCH) + | li AT, LJ_TFUNC + | move TMP2, BASE + | bne CARG4, AT, ->fff_fallback // Traceback must be a function. + | addiu BASE, BASE, 16 + | // Remember active hook before pcall. + | srl TMP3, TMP3, HOOK_ACTIVE_SHIFT + | sdc1 FARG2, 0(TMP2) // Swap function and traceback. + | andi TMP3, TMP3, 1 + | sdc1 FARG1, 8(TMP2) + | addiu PC, TMP3, 16+FRAME_PCALL + | b ->vm_call_dispatch + |. addiu NARGS8:RC, NARGS8:RC, -16 + | + |//-- Coroutine library -------------------------------------------------- + | + |.macro coroutine_resume_wrap, resume + |.if resume + |.ffunc_1 coroutine_resume + | li AT, LJ_TTHREAD + | bne CARG3, AT, ->fff_fallback + |.else + |.ffunc coroutine_wrap_aux + | lw L:CARG1, CFUNC:RB->upvalue[0].gcr + |.endif + | lbu TMP0, L:CARG1->status + | lw TMP1, L:CARG1->cframe + | lw CARG2, L:CARG1->top + | lw TMP2, L:CARG1->base + | addiu TMP3, TMP0, -LUA_YIELD + | bgtz TMP3, ->fff_fallback // st > LUA_YIELD? + |. xor TMP2, TMP2, CARG2 + | bnez TMP1, ->fff_fallback // cframe != 0? + |. or AT, TMP2, TMP0 + | lw TMP0, L:CARG1->maxstack + | beqz AT, ->fff_fallback // base == top && st == 0? + |. lw PC, FRAME_PC(BASE) + | addu TMP2, CARG2, NARGS8:RC + | sltu AT, TMP0, TMP2 + | bnez AT, ->fff_fallback // Stack overflow? + |. sw PC, SAVE_PC + | sw BASE, L->base + |1: + |.if resume + | addiu BASE, BASE, 8 // Keep resumed thread in stack for GC. + | addiu NARGS8:RC, NARGS8:RC, -8 + | addiu TMP2, TMP2, -8 + |.endif + | sw TMP2, L:CARG1->top + | addu TMP1, BASE, NARGS8:RC + | move CARG3, CARG2 + | sw BASE, L->top + |2: // Move args to coroutine. + | ldc1 f0, 0(BASE) + | sltu AT, BASE, TMP1 + | beqz AT, >3 + |. addiu BASE, BASE, 8 + | sdc1 f0, 0(CARG3) + | b <2 + |. addiu CARG3, CARG3, 8 + |3: + | bal ->vm_resume // (lua_State *L, TValue *base, 0, 0) + |. move L:RA, L:CARG1 + | // Returns thread status. + |4: + | lw TMP2, L:RA->base + | sltiu AT, CRET1, LUA_YIELD+1 + | lw TMP3, L:RA->top + | li_vmstate INTERP + | lw BASE, L->base + | st_vmstate + | beqz AT, >8 + |. subu RD, TMP3, TMP2 + | lw TMP0, L->maxstack + | beqz RD, >6 // No results? + |. addu TMP1, BASE, RD + | sltu AT, TMP0, TMP1 + | bnez AT, >9 // Need to grow stack? + |. addu TMP3, TMP2, RD + | sw TMP2, L:RA->top // Clear coroutine stack. + | move TMP1, BASE + |5: // Move results from coroutine. + | ldc1 f0, 0(TMP2) + | addiu TMP2, TMP2, 8 + | sltu AT, TMP2, TMP3 + | sdc1 f0, 0(TMP1) + | bnez AT, <5 + |. addiu TMP1, TMP1, 8 + |6: + | andi TMP0, PC, FRAME_TYPE + |.if resume + | li TMP1, LJ_TTRUE + | addiu RA, BASE, -8 + | sw TMP1, -8+HI(BASE) // Prepend true to results. + | addiu RD, RD, 16 + |.else + | move RA, BASE + | addiu RD, RD, 8 + |.endif + |7: + | sw PC, SAVE_PC + | beqz TMP0, ->BC_RET_Z + |. move MULTRES, RD + | b ->vm_return + |. nop + | + |8: // Coroutine returned with error (at co->top-1). + |.if resume + | addiu TMP3, TMP3, -8 + | li TMP1, LJ_TFALSE + | ldc1 f0, 0(TMP3) + | sw TMP3, L:RA->top // Remove error from coroutine stack. + | li RD, (2+1)*8 + | sw TMP1, -8+HI(BASE) // Prepend false to results. + | addiu RA, BASE, -8 + | sdc1 f0, 0(BASE) // Copy error message. + | b <7 + |. andi TMP0, PC, FRAME_TYPE + |.else + | load_got lj_ffh_coroutine_wrap_err + | move CARG2, L:RA + | call_intern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co) + |. move CARG1, L + |.endif + | + |9: // Handle stack expansion on return from yield. + | load_got lj_state_growstack + | srl CARG2, RD, 3 + | call_intern lj_state_growstack // (lua_State *L, int n) + |. move CARG1, L + | b <4 + |. li CRET1, 0 + |.endmacro + | + | coroutine_resume_wrap 1 // coroutine.resume + | coroutine_resume_wrap 0 // coroutine.wrap + | + |.ffunc coroutine_yield + | lw TMP0, L->cframe + | addu TMP1, BASE, NARGS8:RC + | sw BASE, L->base + | andi TMP0, TMP0, CFRAME_RESUME + | sw TMP1, L->top + | beqz TMP0, ->fff_fallback + |. li CRET1, LUA_YIELD + | sw r0, L->cframe + | b ->vm_leave_unw + |. sb CRET1, L->status + | + |//-- Math library ------------------------------------------------------- + | + |.ffunc_n math_abs + |. abs.d FRET1, FARG1 + |->fff_resn: + | lw PC, FRAME_PC(BASE) + | addiu RA, BASE, -8 + | b ->fff_res1 + |. sdc1 FRET1, -8(BASE) + | + |->fff_restv: + | // CARG3/CARG1 = TValue result. + | lw PC, FRAME_PC(BASE) + | sw CARG3, -8+HI(BASE) + | addiu RA, BASE, -8 + | sw CARG1, -8+LO(BASE) + |->fff_res1: + | // RA = results, PC = return. + | li RD, (1+1)*8 + |->fff_res: + | // RA = results, RD = (nresults+1)*8, PC = return. + | andi TMP0, PC, FRAME_TYPE + | bnez TMP0, ->vm_return + |. move MULTRES, RD + | lw INS, -4(PC) + | decode_RB8a RB, INS + | decode_RB8b RB + |5: + | sltu AT, RD, RB + | bnez AT, >6 // More results expected? + |. decode_RA8a TMP0, INS + | decode_RA8b TMP0 + | ins_next1 + | // Adjust BASE. KBASE is assumed to be set for the calling frame. + | subu BASE, RA, TMP0 + | ins_next2 + | + |6: // Fill up results with nil. + | addu TMP1, RA, RD + | addiu RD, RD, 8 + | b <5 + |. sw TISNIL, -8+HI(TMP1) + | + |.macro math_extern, func + |->ff_math_ .. func: + | lw CARG3, HI(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. load_got func + | sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |. nop + | call_extern + |. ldc1 FARG1, 0(BASE) + | b ->fff_resn + |. nop + |.endmacro + | + |.macro math_extern2, func + | .ffunc_nn math_ .. func + |. load_got func + | call_extern + |. nop + | b ->fff_resn + |. nop + |.endmacro + | + |.macro math_round, func + | .ffunc_n math_ .. func + |. nop + | bal ->vm_ .. func + |. nop + | b ->fff_resn + |. nop + |.endmacro + | + | math_round floor + | math_round ceil + | + | math_extern log + | math_extern log10 + | math_extern exp + | math_extern sin + | math_extern cos + | math_extern tan + | math_extern asin + | math_extern acos + | math_extern atan + | math_extern sinh + | math_extern cosh + | math_extern tanh + | math_extern2 pow + | math_extern2 atan2 + | math_extern2 fmod + | + |.ffunc_n math_sqrt + |. sqrt.d FRET1, FARG1 + | b ->fff_resn + |. nop + | + |->ff_math_deg: + |.ffunc_n math_rad + |. ldc1 FARG2, CFUNC:RB->upvalue[0] + | b ->fff_resn + |. mul.d FRET1, FARG1, FARG2 + | + |.ffunc_nn math_ldexp + | cvt.w.d FARG2, FARG2 + | load_got ldexp + | mfc1 CARG3, FARG2 + | call_extern + |. nop + | b ->fff_resn + |. nop + | + |.ffunc_n math_frexp + | load_got frexp + | lw PC, FRAME_PC(BASE) + | call_extern + |. addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | lw TMP1, DISPATCH_GL(tmptv)(DISPATCH) + | addiu RA, BASE, -8 + | mtc1 TMP1, FARG2 + | sdc1 FRET1, 0(RA) + | cvt.d.w FARG2, FARG2 + | sdc1 FARG2, 8(RA) + | b ->fff_res + |. li RD, (2+1)*8 + | + |.ffunc_n math_modf + | load_got modf + | lw PC, FRAME_PC(BASE) + | call_extern + |. addiu CARG3, BASE, -8 + | addiu RA, BASE, -8 + | sdc1 FRET1, 0(BASE) + | b ->fff_res + |. li RD, (2+1)*8 + | + |.macro math_minmax, name, ismax + |->ff_ .. name: + | lw CARG3, HI(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. ldc1 FRET1, 0(BASE) + | sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |. addu TMP2, BASE, NARGS8:RC + | addiu TMP1, BASE, 8 + | beq TMP1, TMP2, ->fff_resn + |1: + |. lw CARG3, HI(TMP1) + | ldc1 FARG1, 0(TMP1) + | addiu TMP1, TMP1, 8 + | sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |.if ismax + |. c.olt.d FARG1, FRET1 + |.else + |. c.olt.d FRET1, FARG1 + |.endif + | bne TMP1, TMP2, <1 + |. movf.d FRET1, FARG1 + | b ->fff_resn + |. nop + |.endmacro + | + | math_minmax math_min, 0 + | math_minmax math_max, 1 + | + |//-- String library ----------------------------------------------------- + | + |.ffunc_1 string_len + | li AT, LJ_TSTR + | bne CARG3, AT, ->fff_fallback + |. nop + | b ->fff_resi + |. lw CRET1, STR:CARG1->len + | + |.ffunc string_byte // Only handle the 1-arg case here. + | lw CARG3, HI(BASE) + | lw STR:CARG1, LO(BASE) + | xori AT, NARGS8:RC, 8 + | addiu CARG3, CARG3, -LJ_TSTR + | or AT, AT, CARG3 + | bnez AT, ->fff_fallback // Need exactly 1 string argument. + |. nop + | lw TMP0, STR:CARG1->len + | lbu TMP1, STR:CARG1[1] // Access is always ok (NUL at end). + | addiu RA, BASE, -8 + | sltu RD, r0, TMP0 + | mtc1 TMP1, f0 + | addiu RD, RD, 1 + | cvt.d.w f0, f0 + | lw PC, FRAME_PC(BASE) + | sll RD, RD, 3 // RD = ((str->len != 0)+1)*8 + | b ->fff_res + |. sdc1 f0, 0(RA) + | + |.ffunc string_char // Only handle the 1-arg case here. + | ffgccheck + | lw CARG3, HI(BASE) + | ldc1 FARG1, 0(BASE) + | li AT, 8 + | bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument. + |. sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |. li CARG3, 1 + | cvt.w.d FARG1, FARG1 + | addiu CARG2, sp, ARG5_OFS + | sltiu AT, TMP0, 256 + | mfc1 TMP0, FARG1 + | beqz AT, ->fff_fallback + |. sw TMP0, ARG5 + |->fff_newstr: + | load_got lj_str_new + | sw BASE, L->base + | sw PC, SAVE_PC + | call_intern lj_str_new // (lua_State *L, char *str, size_t l) + |. move CARG1, L + | // Returns GCstr *. + | lw BASE, L->base + | move CARG1, CRET1 + | b ->fff_restv + |. li CARG3, LJ_TSTR + | + |.ffunc string_sub + | ffgccheck + | addiu AT, NARGS8:RC, -16 + | lw CARG3, 16+HI(BASE) + | ldc1 f0, 16(BASE) + | lw TMP0, HI(BASE) + | lw STR:CARG1, LO(BASE) + | bltz AT, ->fff_fallback + | lw CARG2, 8+HI(BASE) + | ldc1 f2, 8(BASE) + | beqz AT, >1 + |. li CARG4, -1 + | cvt.w.d f0, f0 + | sltiu AT, CARG3, LJ_TISNUM + | beqz AT, ->fff_fallback + |. mfc1 CARG4, f0 + |1: + | sltiu AT, CARG2, LJ_TISNUM + | beqz AT, ->fff_fallback + |. li AT, LJ_TSTR + | cvt.w.d f2, f2 + | bne TMP0, AT, ->fff_fallback + |. lw CARG2, STR:CARG1->len + | mfc1 CARG3, f2 + | // STR:CARG1 = str, CARG2 = str->len, CARG3 = start, CARG4 = end + | slt AT, CARG4, r0 + | addiu TMP0, CARG2, 1 + | addu TMP1, CARG4, TMP0 + | slt TMP3, CARG3, r0 + | movn CARG4, TMP1, AT // if (end < 0) end += len+1 + | addu TMP1, CARG3, TMP0 + | movn CARG3, TMP1, TMP3 // if (start < 0) start += len+1 + | li TMP2, 1 + | slt AT, CARG4, r0 + | slt TMP3, r0, CARG3 + | movn CARG4, r0, AT // if (end < 0) end = 0 + | movz CARG3, TMP2, TMP3 // if (start < 1) start = 1 + | slt AT, CARG2, CARG4 + | movn CARG4, CARG2, AT // if (end > len) end = len + | addu CARG2, STR:CARG1, CARG3 + | subu CARG3, CARG4, CARG3 // len = end - start + | addiu CARG2, CARG2, sizeof(GCstr)-1 + | bgez CARG3, ->fff_newstr + |. addiu CARG3, CARG3, 1 // len++ + |->fff_emptystr: // Return empty string. + | addiu STR:CARG1, DISPATCH, DISPATCH_GL(strempty) + | b ->fff_restv + |. li CARG3, LJ_TSTR + | + |.ffunc string_rep // Only handle the 1-char case inline. + | ffgccheck + | lw TMP0, HI(BASE) + | sltiu AT, NARGS8:RC, 16 + | lw CARG4, 8+HI(BASE) + | lw STR:CARG1, LO(BASE) + | addiu TMP0, TMP0, -LJ_TSTR + | ldc1 f0, 8(BASE) + | or AT, AT, TMP0 + | bnez AT, ->fff_fallback + |. sltiu AT, CARG4, LJ_TISNUM + | cvt.w.d f0, f0 + | beqz AT, ->fff_fallback + |. lw TMP0, STR:CARG1->len + | mfc1 CARG3, f0 + | lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) + | li AT, 1 + | blez CARG3, ->fff_emptystr // Count <= 0? + |. sltu AT, AT, TMP0 + | beqz TMP0, ->fff_emptystr // Zero length string? + |. sltu TMP0, TMP1, CARG3 + | or AT, AT, TMP0 + | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) + | bnez AT, ->fff_fallback // Fallback for > 1-char strings. + |. lbu TMP0, STR:CARG1[1] + | addu TMP2, CARG2, CARG3 + |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?). + | addiu TMP2, TMP2, -1 + | sltu AT, CARG2, TMP2 + | bnez AT, <1 + |. sb TMP0, 0(TMP2) + | b ->fff_newstr + |. nop + | + |.ffunc string_reverse + | ffgccheck + | lw CARG3, HI(BASE) + | lw STR:CARG1, LO(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. li AT, LJ_TSTR + | bne CARG3, AT, ->fff_fallback + |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) + | lw CARG3, STR:CARG1->len + | addiu CARG1, STR:CARG1, #STR + | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) + | sltu AT, TMP1, CARG3 + | bnez AT, ->fff_fallback + |. addu TMP3, CARG1, CARG3 + | addu CARG4, CARG2, CARG3 + |1: // Reverse string copy. + | lbu TMP1, 0(CARG1) + | sltu AT, CARG1, TMP3 + | beqz AT, ->fff_newstr + |. addiu CARG1, CARG1, 1 + | addiu CARG4, CARG4, -1 + | b <1 + | sb TMP1, 0(CARG4) + | + |.macro ffstring_case, name, lo + | .ffunc name + | ffgccheck + | lw CARG3, HI(BASE) + | lw STR:CARG1, LO(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. li AT, LJ_TSTR + | bne CARG3, AT, ->fff_fallback + |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) + | lw CARG3, STR:CARG1->len + | addiu CARG1, STR:CARG1, #STR + | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) + | sltu AT, TMP1, CARG3 + | bnez AT, ->fff_fallback + |. addu TMP3, CARG1, CARG3 + | move CARG4, CARG2 + |1: // ASCII case conversion. + | lbu TMP1, 0(CARG1) + | sltu AT, CARG1, TMP3 + | beqz AT, ->fff_newstr + |. addiu TMP0, TMP1, -lo + | xori TMP2, TMP1, 0x20 + | sltiu AT, TMP0, 26 + | movn TMP1, TMP2, AT + | addiu CARG1, CARG1, 1 + | sb TMP1, 0(CARG4) + | b <1 + |. addiu CARG4, CARG4, 1 + |.endmacro + | + |ffstring_case string_lower, 65 + |ffstring_case string_upper, 97 + | + |//-- Table library ------------------------------------------------------ + | + |.ffunc_1 table_getn + | li AT, LJ_TTAB + | bne CARG3, AT, ->fff_fallback + |. load_got lj_tab_len + | call_intern lj_tab_len // (GCtab *t) + |. nop + | // Returns uint32_t (but less than 2^31). + | b ->fff_resi + |. nop + | + |//-- Bit library -------------------------------------------------------- + | + |.macro .ffunc_bit, name + | .ffunc_n bit_..name + |. add.d FARG1, FARG1, TOBIT + | mfc1 CRET1, FARG1 + |.endmacro + | + |.macro .ffunc_bit_op, name, ins + | .ffunc_bit name + | addiu TMP1, BASE, 8 + | addu TMP2, BASE, NARGS8:RC + |1: + | lw CARG4, HI(TMP1) + | beq TMP1, TMP2, ->fff_resi + |. ldc1 FARG1, 0(TMP1) + | sltiu AT, CARG4, LJ_TISNUM + | beqz AT, ->fff_fallback + | add.d FARG1, FARG1, TOBIT + | mfc1 CARG2, FARG1 + | ins CRET1, CRET1, CARG2 + | b <1 + |. addiu TMP1, TMP1, 8 + |.endmacro + | + |.ffunc_bit_op band, and + |.ffunc_bit_op bor, or + |.ffunc_bit_op bxor, xor + | + |.ffunc_bit bswap + | srl TMP0, CRET1, 24 + | srl TMP2, CRET1, 8 + | sll TMP1, CRET1, 24 + | andi TMP2, TMP2, 0xff00 + | or TMP0, TMP0, TMP1 + | andi CRET1, CRET1, 0xff00 + | or TMP0, TMP0, TMP2 + | sll CRET1, CRET1, 8 + | b ->fff_resi + |. or CRET1, TMP0, CRET1 + | + |.ffunc_bit bnot + | b ->fff_resi + |. not CRET1, CRET1 + | + |.macro .ffunc_bit_sh, name, ins, shmod + | .ffunc_nn bit_..name + |. add.d FARG1, FARG1, TOBIT + | add.d FARG2, FARG2, TOBIT + | mfc1 CARG1, FARG1 + | mfc1 CARG2, FARG2 + |.if shmod == 1 + | li AT, 32 + | subu TMP0, AT, CARG2 + | sllv CARG2, CARG1, CARG2 + | srlv CARG1, CARG1, TMP0 + |.elif shmod == 2 + | li AT, 32 + | subu TMP0, AT, CARG2 + | srlv CARG2, CARG1, CARG2 + | sllv CARG1, CARG1, TMP0 + |.endif + | b ->fff_resi + |. ins CRET1, CARG1, CARG2 + |.endmacro + | + |.ffunc_bit_sh lshift, sllv, 0 + |.ffunc_bit_sh rshift, srlv, 0 + |.ffunc_bit_sh arshift, srav, 0 + |// Can't use rotrv, since it's only in MIPS32R2. + |.ffunc_bit_sh rol, or, 1 + |.ffunc_bit_sh ror, or, 2 + | + |.ffunc_bit tobit + |->fff_resi: + | mtc1 CRET1, FRET1 + | b ->fff_resn + |. cvt.d.w FRET1, FRET1 + | + |//----------------------------------------------------------------------- + | + |->fff_fallback: // Call fast function fallback handler. + | // BASE = new base, RB = CFUNC, RC = nargs*8 + | lw TMP3, CFUNC:RB->f + | addu TMP1, BASE, NARGS8:RC + | lw PC, FRAME_PC(BASE) // Fallback may overwrite PC. + | addiu TMP0, TMP1, 8*LUA_MINSTACK + | lw TMP2, L->maxstack + | sw PC, SAVE_PC // Redundant (but a defined value). + | sltu AT, TMP2, TMP0 + | sw BASE, L->base + | sw TMP1, L->top + | bnez AT, >5 // Need to grow stack. + |. move CFUNCADDR, TMP3 + | jalr TMP3 // (lua_State *L) + |. move CARG1, L + | // Either throws an error, or recovers and returns -1, 0 or nresults+1. + | lw BASE, L->base + | sll RD, CRET1, 3 + | bgtz CRET1, ->fff_res // Returned nresults+1? + |. addiu RA, BASE, -8 + |1: // Returned 0 or -1: retry fast path. + | lw TMP0, L->top + | lw LFUNC:RB, FRAME_FUNC(BASE) + | bnez CRET1, ->vm_call_tail // Returned -1? + |. subu NARGS8:RC, TMP0, BASE + | ins_callt // Returned 0: retry fast path. + | + |// Reconstruct previous base for vmeta_call during tailcall. + |->vm_call_tail: + | andi TMP0, PC, FRAME_TYPE + | li AT, -4 + | bnez TMP0, >3 + |. and TMP1, PC, AT + | lbu TMP1, OFS_RA(PC) + | sll TMP1, TMP1, 3 + |3: + | b ->vm_call_dispatch // Resolve again for tailcall. + |. subu TMP2, BASE, TMP1 + | + |5: // Grow stack for fallback handler. + | load_got lj_state_growstack + | li CARG2, LUA_MINSTACK + | call_intern lj_state_growstack // (lua_State *L, int n) + |. move CARG1, L + | lw BASE, L->base + | b <1 + |. li CRET1, 0 // Force retry. + | + |->fff_gcstep: // Call GC step function. + | // BASE = new base, RC = nargs*8 + | move MULTRES, ra + | load_got lj_gc_step + | sw BASE, L->base + | addu TMP0, BASE, NARGS8:RC + | sw PC, SAVE_PC // Redundant (but a defined value). + | sw TMP0, L->top + | call_intern lj_gc_step // (lua_State *L) + |. move CARG1, L + | lw BASE, L->base + | move ra, MULTRES + | lw TMP0, L->top + | lw CFUNC:RB, FRAME_FUNC(BASE) + | jr ra + |. subu NARGS8:RC, TMP0, BASE + | + |//----------------------------------------------------------------------- + |//-- Special dispatch targets ------------------------------------------- + |//----------------------------------------------------------------------- + | + |->vm_record: // Dispatch target for recording phase. +#if LJ_HASJIT + | lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) + | andi AT, TMP3, HOOK_VMEVENT // No recording while in vmevent. + | bnez AT, >5 + | // Decrement the hookcount for consistency, but always do the call. + |. lw TMP2, DISPATCH_GL(hookcount)(DISPATCH) + | andi AT, TMP3, HOOK_ACTIVE + | bnez AT, >1 + |. addiu TMP2, TMP2, -1 + | andi AT, TMP3, LUA_MASKLINE|LUA_MASKCOUNT + | beqz AT, >1 + |. nop + | b >1 + |. sw TMP2, DISPATCH_GL(hookcount)(DISPATCH) +#endif + | + |->vm_rethook: // Dispatch target for return hooks. + | lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) + | andi AT, TMP3, HOOK_ACTIVE // Hook already active? + | beqz AT, >1 + |5: // Re-dispatch to static ins. + |. lw AT, GG_DISP2STATIC(TMP0) // Assumes TMP0 holds DISPATCH+OP*4. + | jr AT + |. nop + | + |->vm_inshook: // Dispatch target for instr/line hooks. + | lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) + | lw TMP2, DISPATCH_GL(hookcount)(DISPATCH) + | andi AT, TMP3, HOOK_ACTIVE // Hook already active? + | bnez AT, <5 + |. andi AT, TMP3, LUA_MASKLINE|LUA_MASKCOUNT + | beqz AT, <5 + |. addiu TMP2, TMP2, -1 + | beqz TMP2, >1 + |. sw TMP2, DISPATCH_GL(hookcount)(DISPATCH) + | andi AT, TMP3, LUA_MASKLINE + | beqz AT, <5 + |1: + |. load_got lj_dispatch_ins + | sw MULTRES, SAVE_MULTRES + | move CARG2, PC + | sw BASE, L->base + | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC. + | call_intern lj_dispatch_ins // (lua_State *L, const BCIns *pc) + |. move CARG1, L + |3: + | lw BASE, L->base + |4: // Re-dispatch to static ins. + | lw INS, -4(PC) + | decode_OP4a TMP1, INS + | decode_OP4b TMP1 + | addu TMP0, DISPATCH, TMP1 + | decode_RD8a RD, INS + | lw AT, GG_DISP2STATIC(TMP0) + | decode_RA8a RA, INS + | decode_RD8b RD + | jr AT + | decode_RA8b RA + | + |->cont_hook: // Continue from hook yield. + | addiu PC, PC, 4 + | b <4 + |. lw MULTRES, -24+LO(RB) // Restore MULTRES for *M ins. + | + |->vm_hotloop: // Hot loop counter underflow. +#if LJ_HASJIT + |NYI +#endif + | + |->vm_callhook: // Dispatch target for call hooks. +#if LJ_HASJIT + | b >1 +#endif + |. move CARG2, PC + | + |->vm_hotcall: // Hot call counter underflow. +#if LJ_HASJIT + | ori CARG2, PC, 1 + |1: +#endif + | load_got lj_dispatch_call + | addu TMP0, BASE, RC + | sw PC, SAVE_PC + | sw BASE, L->base + | subu RA, RA, BASE + | sw TMP0, L->top + | call_intern lj_dispatch_call // (lua_State *L, const BCIns *pc) + |. move CARG1, L + | // Returns ASMFunction. + | lw BASE, L->base + | lw TMP0, L->top + | sw r0, SAVE_PC // Invalidate for subsequent line hook. + | subu NARGS8:RC, TMP0, BASE + | addu RA, BASE, RA + | lw LFUNC:RB, FRAME_FUNC(BASE) + | jr CRET1 + |. lw INS, -4(PC) + | + |//----------------------------------------------------------------------- + |//-- Trace exit handler ------------------------------------------------- + |//----------------------------------------------------------------------- + | + |->vm_exit_handler: +#if LJ_HASJIT + |NYI +#endif + |->vm_exit_interp: +#if LJ_HASJIT + |NYI +#endif + | + |//----------------------------------------------------------------------- + |//-- Math helper functions ---------------------------------------------- + |//----------------------------------------------------------------------- + | + |// Modifies AT, TMP0, FRET1, FRET2, f4. Keeps all others incl. FARG1, FARG2. + |.macro vm_round, func + | lui TMP0, 0x4330 // Hiword of 2^52 (double). + | mtc1 r0, f4 + | mtc1 TMP0, f5 + | abs.d FRET2, FARG1 // |x| + | mfc1 AT, f13 + | c.olt.d 0, FRET2, f4 + | add.d FRET1, FRET2, f4 // (|x| + 2^52) - 2^52 + | bc1f 0, >1 // Truncate only if |x| < 2^52. + |. sub.d FRET1, FRET1, f4 + | slt AT, AT, r0 + |.if "func" == "ceil" + | lui TMP0, 0xbff0 // Hiword of -1 (double). Preserves -0. + |.else + | lui TMP0, 0x3ff0 // Hiword of +1 (double). + |.endif + |.if "func" == "trunc" + | mtc1 TMP0, f5 + | c.olt.d 0, FRET2, FRET1 // |x| < result? + | sub.d FRET2, FRET1, f4 + | movt.d FRET1, FRET2, 0 // If yes, subtract +1. + | neg.d FRET2, FRET1 + | jr ra + |. movn.d FRET1, FRET2, AT // Merge sign bit back in. + |.else + | neg.d FRET2, FRET1 + | mtc1 TMP0, f5 + | movn.d FRET1, FRET2, AT // Merge sign bit back in. + |.if "func" == "ceil" + | c.olt.d 0, FRET1, FARG1 // x > result? + |.else + | c.olt.d 0, FARG1, FRET1 // x < result? + |.endif + | sub.d FRET2, FRET1, f4 // If yes, subtract +-1. + | jr ra + |. movt.d FRET1, FRET2, 0 + |.endif + |1: + | jr ra + |. mov.d FRET1, FARG1 + |.endmacro + | + |->vm_floor: + | vm_round floor + |->vm_ceil: + | vm_round ceil + |->vm_trunc: +#if LJ_HASJIT + | vm_round trunc +#endif + | + |//----------------------------------------------------------------------- + |//-- Miscellaneous functions -------------------------------------------- + |//----------------------------------------------------------------------- + | + |//----------------------------------------------------------------------- + |//-- FFI helper functions ----------------------------------------------- + |//----------------------------------------------------------------------- + | + |// Handler for callback functions. Callback slot number in r1, g in r2. + |->vm_ffi_callback: +#if LJ_HASFFI + |.type CTSTATE, CTState, PC + | saveregs + | lw CTSTATE, GL:r2->ctype_state + | addiu DISPATCH, r2, GG_G2DISP + | load_got lj_ccallback_enter + | sw r1, CTSTATE->cb.slot + | sw CARG1, CTSTATE->cb.gpr[0] + | sw CARG2, CTSTATE->cb.gpr[1] + | sdc1 FARG1, CTSTATE->cb.fpr[0] + | sw CARG3, CTSTATE->cb.gpr[2] + | sw CARG4, CTSTATE->cb.gpr[3] + | sdc1 FARG2, CTSTATE->cb.fpr[1] + | addiu TMP0, sp, CFRAME_SPACE+16 + | sw TMP0, CTSTATE->cb.stack + | sw r0, SAVE_PC // Any value outside of bytecode is ok. + | move CARG2, sp + | call_intern lj_ccallback_enter // (CTState *cts, void *cf) + |. move CARG1, CTSTATE + | // Returns lua_State *. + | lw BASE, L:CRET1->base + | lw RC, L:CRET1->top + | move L, CRET1 + | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | lw LFUNC:RB, FRAME_FUNC(BASE) + | mtc1 TMP3, TOBIT + | li_vmstate INTERP + | li TISNIL, LJ_TNIL + | subu RC, RC, BASE + | st_vmstate + | cvt.d.s TOBIT, TOBIT + | ins_callt +#endif + | + |->cont_ffi_callback: // Return from FFI callback. +#if LJ_HASFFI + | load_got lj_ccallback_leave + | lw CTSTATE, DISPATCH_GL(ctype_state)(DISPATCH) + | sw BASE, L->base + | sw RB, L->top + | sw L, CTSTATE->L + | move CARG2, RA + | call_intern lj_ccallback_leave // (CTState *cts, TValue *o) + |. move CARG1, CTSTATE + | lw CRET1, CTSTATE->cb.gpr[0] + | ldc1 FRET1, CTSTATE->cb.fpr[0] + | lw CRET2, CTSTATE->cb.gpr[1] + | b ->vm_leave_unw + |. ldc1 FRET2, CTSTATE->cb.fpr[1] +#endif + | + |->vm_ffi_call: // Call C function via FFI. + | // Caveat: needs special frame unwinding, see below. +#if LJ_HASFFI + | .type CCSTATE, CCallState, CARG1 + | lw TMP1, CCSTATE->spadj + | lbu CARG2, CCSTATE->nsp + | move TMP2, sp + | subu sp, sp, TMP1 + | sw ra, -4(TMP2) + | sll CARG2, CARG2, 2 + | sw r16, -8(TMP2) + | sw CCSTATE, -12(TMP2) + | move r16, TMP2 + | addiu TMP1, CCSTATE, offsetof(CCallState, stack) + | addiu TMP2, sp, 16 + | beqz CARG2, >2 + |. addu TMP3, TMP1, CARG2 + |1: + | lw TMP0, 0(TMP1) + | addiu TMP1, TMP1, 4 + | sltu AT, TMP1, TMP3 + | sw TMP0, 0(TMP2) + | bnez AT, <1 + |. addiu TMP2, TMP2, 4 + |2: + | lw CFUNCADDR, CCSTATE->func + | lw CARG2, CCSTATE->gpr[1] + | lw CARG3, CCSTATE->gpr[2] + | lw CARG4, CCSTATE->gpr[3] + | ldc1 FARG1, CCSTATE->fpr[0] + | ldc1 FARG2, CCSTATE->fpr[1] + | jalr CFUNCADDR + |. lw CARG1, CCSTATE->gpr[0] // Do this last, since CCSTATE is CARG1. + | lw CCSTATE:TMP1, -12(r16) + | lw TMP2, -8(r16) + | lw ra, -4(r16) + | sw CRET1, CCSTATE:TMP1->gpr[0] + | sw CRET2, CCSTATE:TMP1->gpr[1] + | sdc1 FRET1, CCSTATE:TMP1->fpr[0] + | sdc1 FRET2, CCSTATE:TMP1->fpr[1] + | move sp, r16 + | jr ra + |. move r16, TMP2 +#endif + |// Note: vm_ffi_call must be the last function in this object file! + | + |//----------------------------------------------------------------------- +} + +/* Generate the code for a single instruction. */ +static void build_ins(BuildCtx *ctx, BCOp op, int defop) +{ + int vk = 0; + |=>defop: + + switch (op) { + + /* -- Comparison ops ---------------------------------------------------- */ + + /* Remember: all ops branch for a true comparison, fall through otherwise. */ + + case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: + | // RA = src1*8, RD = src2*8, JMP with RD = target + | addu CARG2, BASE, RA + | addu CARG3, BASE, RD + | lw TMP0, HI(CARG2) + | lw TMP1, HI(CARG3) + | ldc1 f0, 0(CARG2) + | ldc1 f2, 0(CARG3) + | sltiu TMP0, TMP0, LJ_TISNUM + | sltiu TMP1, TMP1, LJ_TISNUM + | lhu TMP2, OFS_RD(PC) + | and TMP0, TMP0, TMP1 + | addiu PC, PC, 4 + | beqz TMP0, ->vmeta_comp + |. lui TMP1, (-(BCBIAS_J*4 >> 16) & 65535) + | decode_RD4b TMP2 + | addu TMP2, TMP2, TMP1 + if (op == BC_ISLT || op == BC_ISGE) { + | c.olt.d f0, f2 + } else { + | c.ole.d f0, f2 + } + if (op == BC_ISLT || op == BC_ISLE) { + | movf TMP2, r0 + } else { + | movt TMP2, r0 + } + | addu PC, PC, TMP2 + |1: + | ins_next + break; + + case BC_ISEQV: case BC_ISNEV: + vk = op == BC_ISEQV; + | // RA = src1*8, RD = src2*8, JMP with RD = target + | addu RA, BASE, RA + | addiu PC, PC, 4 + | lw TMP0, HI(RA) + | ldc1 f0, 0(RA) + | addu RD, BASE, RD + | lhu TMP2, -4+OFS_RD(PC) + | lw TMP1, HI(RD) + | ldc1 f2, 0(RD) + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | sltiu AT, TMP0, LJ_TISNUM + | sltiu CARG1, TMP1, LJ_TISNUM + | decode_RD4b TMP2 + | and AT, AT, CARG1 + | beqz AT, >5 + |. addu TMP2, TMP2, TMP3 + | c.eq.d f0, f2 + if (vk) { + | movf TMP2, r0 + } else { + | movt TMP2, r0 + } + |1: + | addu PC, PC, TMP2 + | ins_next + |5: // Either or both types are not numbers. + | lw CARG2, LO(RA) + | lw CARG3, LO(RD) + if (LJ_HASFFI) { + | li TMP3, LJ_TCDATA + | beq TMP0, TMP3, ->vmeta_equal_cd + } + |. sltiu AT, TMP0, LJ_TISPRI // Not a primitive? + if (LJ_HASFFI) { + | beq TMP1, TMP3, ->vmeta_equal_cd + } + |. xor TMP3, CARG2, CARG3 // Same tv? + | xor TMP1, TMP1, TMP0 // Same type? + | sltiu CARG1, TMP0, LJ_TISTABUD+1 // Table or userdata? + | movz TMP3, r0, AT // Ignore tv if primitive. + | movn CARG1, r0, TMP1 // Tab/ud and same type? + | or AT, TMP1, TMP3 // Same type && (pri||same tv). + | movz CARG1, r0, AT + | beqz CARG1, <1 // Done if not tab/ud or not same type or same tv. + if (vk) { + |. movn TMP2, r0, AT + } else { + |. movz TMP2, r0, AT + } + | // Different tables or userdatas. Need to check __eq metamethod. + | // Field metatable must be at same offset for GCtab and GCudata! + | lw TAB:TMP1, TAB:CARG2->metatable + | beqz TAB:TMP1, <1 // No metatable? + |. nop + | lbu TMP1, TAB:TMP1->nomm + | andi TMP1, TMP1, 1<vmeta_equal // Handle __eq metamethod. + |. li CARG4, 1-vk // ne = 0 or 1. + break; + + case BC_ISEQS: case BC_ISNES: + vk = op == BC_ISEQS; + | // RA = src*8, RD = str_const*8 (~), JMP with RD = target + | addu RA, BASE, RA + | addiu PC, PC, 4 + | lw TMP0, HI(RA) + | srl RD, RD, 1 + | lw STR:TMP3, LO(RA) + | subu RD, KBASE, RD + | lhu TMP2, -4+OFS_RD(PC) + if (LJ_HASFFI) { + | li AT, LJ_TCDATA + | beq TMP0, AT, ->vmeta_equal_cd + } + |. lw STR:TMP1, -4(RD) // KBASE-4-str_const*4 + | addiu TMP0, TMP0, -LJ_TSTR + | decode_RD4b TMP2 + | xor TMP1, STR:TMP1, STR:TMP3 + | or TMP0, TMP0, TMP1 + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | addu TMP2, TMP2, TMP3 + if (vk) { + | movn TMP2, r0, TMP0 + } else { + | movz TMP2, r0, TMP0 + } + | addu PC, PC, TMP2 + | ins_next + break; + + case BC_ISEQN: case BC_ISNEN: + vk = op == BC_ISEQN; + | // RA = src*8, RD = num_const*8, JMP with RD = target + | addu RA, BASE, RA + | addiu PC, PC, 4 + | lw TMP0, HI(RA) + | ldc1 f0, 0(RA) + | addu RD, KBASE, RD + | lhu TMP2, -4+OFS_RD(PC) + | ldc1 f2, 0(RD) + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | sltiu AT, TMP0, LJ_TISNUM + | decode_RD4b TMP2 + if (LJ_HASFFI) { + | beqz AT, >5 + } else { + | beqz AT, >1 + } + |. addu TMP2, TMP2, TMP3 + | c.eq.d f0, f2 + if (vk) { + | movf TMP2, r0 + | addu PC, PC, TMP2 + |1: + } else { + | movt TMP2, r0 + |1: + | addu PC, PC, TMP2 + } + | ins_next + if (LJ_HASFFI) { + |5: + | li AT, LJ_TCDATA + | beq TMP0, AT, ->vmeta_equal_cd + |. nop + | b <1 + |. nop + } + break; + + case BC_ISEQP: case BC_ISNEP: + vk = op == BC_ISEQP; + | // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target + | addu RA, BASE, RA + | srl TMP1, RD, 3 + | lw TMP0, HI(RA) + | lhu TMP2, OFS_RD(PC) + | not TMP1, TMP1 + | addiu PC, PC, 4 + if (LJ_HASFFI) { + | li AT, LJ_TCDATA + | beq TMP0, AT, ->vmeta_equal_cd + } + |. xor TMP0, TMP0, TMP1 + | decode_RD4b TMP2 + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | addu TMP2, TMP2, TMP3 + if (vk) { + | movn TMP2, r0, TMP0 + } else { + | movz TMP2, r0, TMP0 + } + | addu PC, PC, TMP2 + | ins_next + break; + + /* -- Unary test and copy ops ------------------------------------------- */ + + case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF: + | // RA = dst*8 or unused, RD = src*8, JMP with RD = target + | addu RD, BASE, RD + | lhu TMP2, OFS_RD(PC) + | lw TMP0, HI(RD) + | addiu PC, PC, 4 + if (op == BC_IST || op == BC_ISF) { + | sltiu TMP0, TMP0, LJ_TISTRUECOND + | decode_RD4b TMP2 + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | addu TMP2, TMP2, TMP3 + if (op == BC_IST) { + | movz TMP2, r0, TMP0 + } else { + | movn TMP2, r0, TMP0 + } + | addu PC, PC, TMP2 + } else { + | sltiu TMP0, TMP0, LJ_TISTRUECOND + | ldc1 f0, 0(RD) + if (op == BC_ISTC) { + | beqz TMP0, >1 + } else { + | bnez TMP0, >1 + } + |. addu RA, BASE, RA + | decode_RD4b TMP2 + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | addu TMP2, TMP2, TMP3 + | sdc1 f0, 0(RA) + | addu PC, PC, TMP2 + |1: + } + | ins_next + break; + + /* -- Unary ops --------------------------------------------------------- */ + + case BC_MOV: + | // RA = dst*8, RD = src*8 + | addu RD, BASE, RD + | addu RA, BASE, RA + | ldc1 f0, 0(RD) + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + break; + case BC_NOT: + | // RA = dst*8, RD = src*8 + | addu RD, BASE, RD + | addu RA, BASE, RA + | lw TMP0, HI(RD) + | li TMP1, LJ_TFALSE + | sltiu TMP0, TMP0, LJ_TISTRUECOND + | addiu TMP1, TMP0, LJ_TTRUE + | ins_next1 + | sw TMP1, HI(RA) + | ins_next2 + break; + case BC_UNM: + | // RA = dst*8, RD = src*8 + | addu CARG3, BASE, RD + | addu RA, BASE, RA + | lw TMP0, HI(CARG3) + | ldc1 f0, 0(CARG3) + | sltiu AT, TMP0, LJ_TISNUM + | beqz AT, ->vmeta_unm + |. neg.d f0, f0 + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + break; + case BC_LEN: + | // RA = dst*8, RD = src*8 + | addu CARG2, BASE, RD + | addu RA, BASE, RA + | lw TMP0, HI(CARG2) + | lw CARG1, LO(CARG2) + | li AT, LJ_TSTR + | bne TMP0, AT, >2 + |. li AT, LJ_TTAB + | lw CRET1, STR:CARG1->len + |1: + | mtc1 CRET1, f0 + | cvt.d.w f0, f0 + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + |2: + | bne TMP0, AT, ->vmeta_len + |. nop +#ifdef LUAJIT_ENABLE_LUA52COMPAT + | lw TAB:TMP2, TAB:CARG1->metatable + | bnez TAB:TMP2, >9 + |. nop + |3: +#endif + |->BC_LEN_Z: + | load_got lj_tab_len + | call_intern lj_tab_len // (GCtab *t) + |. nop + | // Returns uint32_t (but less than 2^31). + | b <1 + |. nop +#ifdef LUAJIT_ENABLE_LUA52COMPAT + |9: + | lbu TMP0, TAB:TMP2->nomm + | andi TMP0, TMP0, 1<vmeta_len + |. nop +#endif + break; + + /* -- Binary ops -------------------------------------------------------- */ + + |.macro ins_arithpre + ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8 + ||switch (vk) { + ||case 0: + | addu CARG3, BASE, RB + | addu CARG4, KBASE, RC + | lw TMP1, HI(CARG3) + | ldc1 f20, 0(CARG3) + | ldc1 f22, 0(CARG4) + | sltiu AT, TMP1, LJ_TISNUM + || break; + ||case 1: + | addu CARG4, BASE, RB + | addu CARG3, KBASE, RC + | lw TMP1, HI(CARG4) + | ldc1 f22, 0(CARG4) + | ldc1 f20, 0(CARG3) + | sltiu AT, TMP1, LJ_TISNUM + || break; + ||default: + | addu CARG3, BASE, RB + | addu CARG4, BASE, RC + | lw TMP1, HI(CARG3) + | lw TMP2, HI(CARG4) + | ldc1 f20, 0(CARG3) + | ldc1 f22, 0(CARG4) + | sltiu AT, TMP1, LJ_TISNUM + | sltiu TMP0, TMP2, LJ_TISNUM + | and AT, AT, TMP0 + || break; + ||} + | beqz AT, ->vmeta_arith + |. addu RA, BASE, RA + |.endmacro + | + |.macro fpmod, a, b, c + |->BC_MODVN_Z: + | bal ->vm_floor // floor(b/c) + |. div.d FARG1, b, c + | mul.d a, FRET1, c + | sub.d a, b, a // b - floor(b/c)*c + |.endmacro + | + |.macro ins_arith, ins + | ins_arithpre + |.if "ins" == "fpmod_" + | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. + |. nop + |.else + | ins f0, f20, f22 + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + |.endif + |.endmacro + + case BC_ADDVN: case BC_ADDNV: case BC_ADDVV: + | ins_arith add.d + break; + case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: + | ins_arith sub.d + break; + case BC_MULVN: case BC_MULNV: case BC_MULVV: + | ins_arith mul.d + break; + case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: + | ins_arith div.d + break; + case BC_MODVN: + | ins_arith fpmod + break; + case BC_MODNV: case BC_MODVV: + | ins_arith fpmod_ + break; + case BC_POW: + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | addu CARG3, BASE, RB + | addu CARG4, BASE, RC + | lw TMP1, HI(CARG3) + | lw TMP2, HI(CARG4) + | ldc1 FARG1, 0(CARG3) + | ldc1 FARG2, 0(CARG4) + | sltiu AT, TMP1, LJ_TISNUM + | sltiu TMP0, TMP2, LJ_TISNUM + | and AT, AT, TMP0 + | load_got pow + | beqz AT, ->vmeta_arith + |. addu RA, BASE, RA + | call_extern + |. nop + | ins_next1 + | sdc1 FRET1, 0(RA) + | ins_next2 + break; + + case BC_CAT: + | // RA = dst*8, RB = src_start*8, RC = src_end*8 + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | subu CARG3, RC, RB + | sw BASE, L->base + | addu CARG2, BASE, RC + | move MULTRES, RB + |->BC_CAT_Z: + | load_got lj_meta_cat + | srl CARG3, CARG3, 3 + | sw PC, SAVE_PC + | call_intern lj_meta_cat // (lua_State *L, TValue *top, int left) + |. move CARG1, L + | // Returns NULL (finished) or TValue * (metamethod). + | bnez CRET1, ->vmeta_binop + |. lw BASE, L->base + | addu RB, BASE, MULTRES + | ldc1 f0, 0(RB) + | addu RA, BASE, RA + | ins_next1 + | sdc1 f0, 0(RA) // Copy result from RB to RA. + | ins_next2 + break; + + /* -- Constant ops ------------------------------------------------------ */ + + case BC_KSTR: + | // RA = dst*8, RD = str_const*8 (~) + | srl TMP1, RD, 1 + | subu TMP1, KBASE, TMP1 + | ins_next1 + | lw TMP0, -4(TMP1) // KBASE-4-str_const*4 + | addu RA, BASE, RA + | li TMP2, LJ_TSTR + | sw TMP0, LO(RA) + | sw TMP2, HI(RA) + | ins_next2 + break; + case BC_KCDATA: +#if LJ_HASFFI + | // RA = dst*8, RD = cdata_const*8 (~) + | srl TMP1, RD, 1 + | subu TMP1, KBASE, TMP1 + | ins_next1 + | lw TMP0, -4(TMP1) // KBASE-4-cdata_const*4 + | addu RA, BASE, RA + | li TMP2, LJ_TCDATA + | sw TMP0, LO(RA) + | sw TMP2, HI(RA) + | ins_next2 +#endif + break; + case BC_KSHORT: + | // RA = dst*8, RD = int16_literal*8 + | sra RD, INS, 16 + | mtc1 RD, f0 + | addu RA, BASE, RA + | cvt.d.w f0, f0 + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + break; + case BC_KNUM: + | // RA = dst*8, RD = num_const*8 + | addu RD, KBASE, RD + | addu RA, BASE, RA + | ldc1 f0, 0(RD) + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + break; + case BC_KPRI: + | // RA = dst*8, RD = primitive_type*8 (~) + | srl TMP1, RD, 3 + | addu RA, BASE, RA + | not TMP0, TMP1 + | ins_next1 + | sw TMP0, HI(RA) + | ins_next2 + break; + case BC_KNIL: + | // RA = base*8, RD = end*8 + | addu RA, BASE, RA + | sw TISNIL, HI(RA) + | addiu RA, RA, 8 + | addu RD, BASE, RD + |1: + | sw TISNIL, HI(RA) + | slt AT, RA, RD + | bnez AT, <1 + |. addiu RA, RA, 8 + | ins_next_ + break; + + /* -- Upvalue and function ops ------------------------------------------ */ + + case BC_UGET: + | // RA = dst*8, RD = uvnum*8 + | lw LFUNC:RB, FRAME_FUNC(BASE) + | srl RD, RD, 1 + | addu RD, RD, LFUNC:RB + | lw UPVAL:RB, LFUNC:RD->uvptr + | ins_next1 + | lw TMP1, UPVAL:RB->v + | ldc1 f0, 0(TMP1) + | addu RA, BASE, RA + | sdc1 f0, 0(RA) + | ins_next2 + break; + case BC_USETV: + | // RA = uvnum*8, RD = src*8 + | lw LFUNC:RB, FRAME_FUNC(BASE) + | srl RA, RA, 1 + | addu RD, BASE, RD + | addu RA, RA, LFUNC:RB + | ldc1 f0, 0(RD) + | lw UPVAL:RB, LFUNC:RA->uvptr + | lbu TMP3, UPVAL:RB->marked + | lw CARG2, UPVAL:RB->v + | andi TMP3, TMP3, LJ_GC_BLACK // isblack(uv) + | lbu TMP0, UPVAL:RB->closed + | lw TMP2, HI(RD) + | sdc1 f0, 0(CARG2) + | li AT, LJ_GC_BLACK|1 + | or TMP3, TMP3, TMP0 + | beq TMP3, AT, >2 // Upvalue is closed and black? + |. addiu TMP2, TMP2, -(LJ_TISNUM+1) + |1: + | ins_next + | + |2: // Check if new value is collectable. + | sltiu AT, TMP2, LJ_TISGCV - (LJ_TISNUM+1) + | beqz AT, <1 // tvisgcv(v) + |. lw TMP1, LO(RD) + | lbu TMP3, GCOBJ:TMP1->gch.marked + | andi TMP3, TMP3, LJ_GC_WHITES // iswhite(v) + | beqz TMP3, <1 + |. load_got lj_gc_barrieruv + | // Crossed a write barrier. Move the barrier forward. + | call_intern lj_gc_barrieruv // (global_State *g, TValue *tv) + |. addiu CARG1, DISPATCH, GG_DISP2G + | b <1 + |. nop + break; + case BC_USETS: + | // RA = uvnum*8, RD = str_const*8 (~) + | lw LFUNC:RB, FRAME_FUNC(BASE) + | srl RA, RA, 1 + | srl TMP1, RD, 1 + | addu RA, RA, LFUNC:RB + | subu TMP1, KBASE, TMP1 + | lw UPVAL:RB, LFUNC:RA->uvptr + | lw STR:TMP1, -4(TMP1) // KBASE-4-str_const*4 + | lbu TMP2, UPVAL:RB->marked + | lw CARG2, UPVAL:RB->v + | lbu TMP3, STR:TMP1->marked + | andi AT, TMP2, LJ_GC_BLACK // isblack(uv) + | lbu TMP2, UPVAL:RB->closed + | li TMP0, LJ_TSTR + | sw STR:TMP1, LO(CARG2) + | bnez AT, >2 + |. sw TMP0, HI(CARG2) + |1: + | ins_next + | + |2: // Check if string is white and ensure upvalue is closed. + | beqz TMP2, <1 + |. andi AT, TMP3, LJ_GC_WHITES // iswhite(str) + | beqz AT, <1 + |. load_got lj_gc_barrieruv + | // Crossed a write barrier. Move the barrier forward. + | call_intern lj_gc_barrieruv // (global_State *g, TValue *tv) + |. addiu CARG1, DISPATCH, GG_DISP2G + | b <1 + |. nop + break; + case BC_USETN: + | // RA = uvnum*8, RD = num_const*8 + | lw LFUNC:RB, FRAME_FUNC(BASE) + | srl RA, RA, 1 + | addu RD, KBASE, RD + | addu RA, RA, LFUNC:RB + | ldc1 f0, 0(RD) + | lw UPVAL:RB, LFUNC:RA->uvptr + | ins_next1 + | lw TMP1, UPVAL:RB->v + | sdc1 f0, 0(TMP1) + | ins_next2 + break; + case BC_USETP: + | // RA = uvnum*8, RD = primitive_type*8 (~) + | lw LFUNC:RB, FRAME_FUNC(BASE) + | srl RA, RA, 1 + | srl TMP0, RD, 3 + | addu RA, RA, LFUNC:RB + | not TMP0, TMP0 + | lw UPVAL:RB, LFUNC:RA->uvptr + | ins_next1 + | lw TMP1, UPVAL:RB->v + | sw TMP0, HI(TMP1) + | ins_next2 + break; + + case BC_UCLO: + | // RA = level*8, RD = target + | lw TMP2, L->openupval + | branch_RD // Do this first since RD is not saved. + | load_got lj_func_closeuv + | sw BASE, L->base + | beqz TMP2, >1 + |. move CARG1, L + | call_intern lj_func_closeuv // (lua_State *L, TValue *level) + |. addu CARG2, BASE, RA + | lw BASE, L->base + |1: + | ins_next + break; + + case BC_FNEW: + | // RA = dst*8, RD = proto_const*8 (~) (holding function prototype) + | srl TMP1, RD, 1 + | load_got lj_func_newL_gc + | subu TMP1, KBASE, TMP1 + | lw CARG3, FRAME_FUNC(BASE) + | lw CARG2, -4(TMP1) // KBASE-4-tab_const*4 + | sw BASE, L->base + | sw PC, SAVE_PC + | // (lua_State *L, GCproto *pt, GCfuncL *parent) + | call_intern lj_func_newL_gc + |. move CARG1, L + | // Returns GCfuncL *. + | lw BASE, L->base + | li TMP0, LJ_TFUNC + | ins_next1 + | addu RA, BASE, RA + | sw TMP0, HI(RA) + | sw LFUNC:CRET1, LO(RA) + | ins_next2 + break; + + /* -- Table ops --------------------------------------------------------- */ + + case BC_TNEW: + case BC_TDUP: + | // RA = dst*8, RD = (hbits|asize)*8 | tab_const*8 (~) + | lw TMP0, DISPATCH_GL(gc.total)(DISPATCH) + | lw TMP1, DISPATCH_GL(gc.threshold)(DISPATCH) + | sw BASE, L->base + | sw PC, SAVE_PC + | sltu AT, TMP0, TMP1 + | beqz AT, >5 + |1: + if (op == BC_TNEW) { + | load_got lj_tab_new + | srl CARG2, RD, 3 + | andi CARG2, CARG2, 0x7ff + | li TMP0, 0x801 + | addiu AT, CARG2, -0x7ff + | srl CARG3, RD, 14 + | movz CARG2, TMP0, AT + | // (lua_State *L, int32_t asize, uint32_t hbits) + | call_intern lj_tab_new + |. move CARG1, L + | // Returns Table *. + } else { + | load_got lj_tab_dup + | srl TMP1, RD, 1 + | subu TMP1, KBASE, TMP1 + | move CARG1, L + | call_intern lj_tab_dup // (lua_State *L, Table *kt) + |. lw CARG2, -4(TMP1) // KBASE-4-str_const*4 + | // Returns Table *. + } + | lw BASE, L->base + | ins_next1 + | addu RA, BASE, RA + | li TMP0, LJ_TTAB + | sw TAB:CRET1, LO(RA) + | sw TMP0, HI(RA) + | ins_next2 + |5: + | load_got lj_gc_step_fixtop + | move MULTRES, RD + | call_intern lj_gc_step_fixtop // (lua_State *L) + |. move CARG1, L + | b <1 + |. move RD, MULTRES + break; + + case BC_GGET: + | // RA = dst*8, RD = str_const*8 (~) + case BC_GSET: + | // RA = src*8, RD = str_const*8 (~) + | lw LFUNC:TMP2, FRAME_FUNC(BASE) + | srl TMP1, RD, 1 + | subu TMP1, KBASE, TMP1 + | lw TAB:RB, LFUNC:TMP2->env + | lw STR:RC, -4(TMP1) // KBASE-4-str_const*4 + if (op == BC_GGET) { + | b ->BC_TGETS_Z + } else { + | b ->BC_TSETS_Z + } + |. addu RA, BASE, RA + break; + + case BC_TGETV: + | // RA = dst*8, RB = table*8, RC = key*8 + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | addu CARG2, BASE, RB + | addu CARG3, BASE, RC + | lw TMP1, HI(CARG2) + | lw TMP2, HI(CARG3) + | lw TAB:RB, LO(CARG2) + | li AT, LJ_TTAB + | ldc1 f0, 0(CARG3) + | bne TMP1, AT, ->vmeta_tgetv + |. addu RA, BASE, RA + | sltiu AT, TMP2, LJ_TISNUM + | beqz AT, >5 + |. li AT, LJ_TSTR + | + | // Convert number key to integer, check for integerness and range. + | cvt.w.d f2, f0 + | lw TMP0, TAB:RB->asize + | mfc1 TMP2, f2 + | cvt.d.w f4, f2 + | lw TMP1, TAB:RB->array + | c.eq.d f0, f4 + | sltu AT, TMP2, TMP0 + | movf AT, r0 + | sll TMP2, TMP2, 3 + | beqz AT, ->vmeta_tgetv // Integer key and in array part? + |. addu TMP2, TMP1, TMP2 + | lw TMP0, HI(TMP2) + | beq TMP0, TISNIL, >2 + |. ldc1 f0, 0(TMP2) + |1: + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + | + |2: // Check for __index if table value is nil. + | lw TAB:TMP2, TAB:RB->metatable + | beqz TAB:TMP2, <1 // No metatable: done. + |. nop + | lbu TMP0, TAB:TMP2->nomm + | andi TMP0, TMP0, 1<vmeta_tgetv + |. nop + | + |5: + | bne TMP2, AT, ->vmeta_tgetv + |. lw STR:RC, LO(CARG3) + | b ->BC_TGETS_Z // String key? + |. nop + break; + case BC_TGETS: + | // RA = dst*8, RB = table*8, RC = str_const*4 (~) + | decode_RB8a RB, INS + | decode_RB8b RB + | addu CARG2, BASE, RB + | decode_RC4a RC, INS + | lw TMP0, HI(CARG2) + | decode_RC4b RC + | li AT, LJ_TTAB + | lw TAB:RB, LO(CARG2) + | subu CARG3, KBASE, RC + | lw STR:RC, -4(CARG3) // KBASE-4-str_const*4 + | bne TMP0, AT, ->vmeta_tgets1 + |. addu RA, BASE, RA + |->BC_TGETS_Z: + | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8 + | lw TMP0, TAB:RB->hmask + | lw TMP1, STR:RC->hash + | lw NODE:TMP2, TAB:RB->node + | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask + | sll TMP0, TMP1, 5 + | sll TMP1, TMP1, 3 + | subu TMP1, TMP0, TMP1 + | addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) + |1: + | lw CARG1, offsetof(Node, key)+HI(NODE:TMP2) + | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) + | lw NODE:TMP1, NODE:TMP2->next + | lw CARG2, offsetof(Node, val)+HI(NODE:TMP2) + | addiu CARG1, CARG1, -LJ_TSTR + | xor TMP0, TMP0, STR:RC + | or AT, CARG1, TMP0 + | bnez AT, >4 + |. lw TAB:TMP3, TAB:RB->metatable + | beq CARG2, TISNIL, >5 // Key found, but nil value? + |. lw CARG1, offsetof(Node, val)+LO(NODE:TMP2) + |3: + | ins_next1 + | sw CARG2, HI(RA) + | sw CARG1, LO(RA) + | ins_next2 + | + |4: // Follow hash chain. + | bnez NODE:TMP1, <1 + |. move NODE:TMP2, NODE:TMP1 + | // End of hash chain: key not found, nil result. + | + |5: // Check for __index if table value is nil. + | beqz TAB:TMP3, <3 // No metatable: done. + |. li CARG2, LJ_TNIL + | lbu TMP0, TAB:TMP3->nomm + | andi TMP0, TMP0, 1<vmeta_tgets + |. nop + break; + case BC_TGETB: + | // RA = dst*8, RB = table*8, RC = index*8 + | decode_RB8a RB, INS + | decode_RB8b RB + | addu CARG2, BASE, RB + | decode_RDtoRC8 RC, RD + | lw CARG1, HI(CARG2) + | li AT, LJ_TTAB + | lw TAB:RB, LO(CARG2) + | addu RA, BASE, RA + | bne CARG1, AT, ->vmeta_tgetb + |. srl TMP0, RC, 3 + | lw TMP1, TAB:RB->asize + | lw TMP2, TAB:RB->array + | sltu AT, TMP0, TMP1 + | beqz AT, ->vmeta_tgetb + |. addu RC, TMP2, RC + | lw TMP1, HI(RC) + | beq TMP1, TISNIL, >5 + |. ldc1 f0, 0(RC) + |1: + | ins_next1 + | sdc1 f0, 0(RA) + | ins_next2 + | + |5: // Check for __index if table value is nil. + | lw TAB:TMP2, TAB:RB->metatable + | beqz TAB:TMP2, <1 // No metatable: done. + |. nop + | lbu TMP1, TAB:TMP2->nomm + | andi TMP1, TMP1, 1<vmeta_tgetb // Caveat: preserve TMP0! + |. nop + break; + + case BC_TSETV: + | // RA = src*8, RB = table*8, RC = key*8 + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | addu CARG2, BASE, RB + | addu CARG3, BASE, RC + | lw TMP1, HI(CARG2) + | lw TMP2, HI(CARG3) + | lw TAB:RB, LO(CARG2) + | li AT, LJ_TTAB + | ldc1 f0, 0(CARG3) + | bne TMP1, AT, ->vmeta_tsetv + |. addu RA, BASE, RA + | sltiu AT, TMP2, LJ_TISNUM + | beqz AT, >5 + |. li AT, LJ_TSTR + | + | // Convert number key to integer, check for integerness and range. + | cvt.w.d f2, f0 + | lw TMP0, TAB:RB->asize + | mfc1 TMP2, f2 + | cvt.d.w f4, f2 + | lw TMP1, TAB:RB->array + | c.eq.d f0, f4 + | sltu AT, TMP2, TMP0 + | movf AT, r0 + | sll TMP2, TMP2, 3 + | beqz AT, ->vmeta_tsetv // Integer key and in array part? + |. addu TMP1, TMP1, TMP2 + | lbu TMP3, TAB:RB->marked + | lw TMP0, HI(TMP1) + | beq TMP0, TISNIL, >3 + |. ldc1 f0, 0(RA) + |1: + | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | bnez AT, >7 + |. sdc1 f0, 0(TMP1) + |2: + | ins_next + | + |3: // Check for __newindex if previous value is nil. + | lw TAB:TMP2, TAB:RB->metatable + | beqz TAB:TMP2, <1 // No metatable: done. + |. nop + | lbu TMP2, TAB:TMP2->nomm + | andi TMP2, TMP2, 1<vmeta_tsetv + |. nop + | + |5: + | bne TMP2, AT, ->vmeta_tsetv + |. lw STR:RC, LO(CARG3) + | b ->BC_TSETS_Z // String key? + |. nop + | + |7: // Possible table write barrier for the value. Skip valiswhite check. + | barrierback TAB:RB, TMP3, TMP0, <2 + break; + case BC_TSETS: + | // RA = src*8, RB = table*8, RC = str_const*8 (~) + | decode_RB8a RB, INS + | decode_RB8b RB + | addu CARG2, BASE, RB + | decode_RC4a RC, INS + | lw TMP0, HI(CARG2) + | decode_RC4b RC + | li AT, LJ_TTAB + | subu CARG3, KBASE, RC + | lw TAB:RB, LO(CARG2) + | lw STR:RC, -4(CARG3) // KBASE-4-str_const*4 + | bne TMP0, AT, ->vmeta_tsets1 + |. addu RA, BASE, RA + |->BC_TSETS_Z: + | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = BASE+src*8 + | lw TMP0, TAB:RB->hmask + | lw TMP1, STR:RC->hash + | lw NODE:TMP2, TAB:RB->node + | sb r0, TAB:RB->nomm // Clear metamethod cache. + | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask + | sll TMP0, TMP1, 5 + | sll TMP1, TMP1, 3 + | subu TMP1, TMP0, TMP1 + | addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) + | ldc1 f20, 0(RA) + |1: + | lw CARG1, offsetof(Node, key)+HI(NODE:TMP2) + | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) + | li AT, LJ_TSTR + | lw NODE:TMP1, NODE:TMP2->next + | bne CARG1, AT, >5 + |. lw CARG2, offsetof(Node, val)+HI(NODE:TMP2) + | bne TMP0, STR:RC, >5 + |. lbu TMP3, TAB:RB->marked + | beq CARG2, TISNIL, >4 // Key found, but nil value? + |. lw TAB:TMP0, TAB:RB->metatable + |2: + | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | bnez AT, >7 + |. sdc1 f20, NODE:TMP2->val + |3: + | ins_next + | + |4: // Check for __newindex if previous value is nil. + | beqz TAB:TMP0, <2 // No metatable: done. + |. nop + | lbu TMP0, TAB:TMP0->nomm + | andi TMP0, TMP0, 1<vmeta_tsets + |. nop + | + |5: // Follow hash chain. + | bnez NODE:TMP1, <1 + |. move NODE:TMP2, NODE:TMP1 + | // End of hash chain: key not found, add a new one + | + | // But check for __newindex first. + | lw TAB:TMP2, TAB:RB->metatable + | beqz TAB:TMP2, >6 // No metatable: continue. + |. addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) + | lbu TMP0, TAB:TMP2->nomm + | andi TMP0, TMP0, 1<vmeta_tsets // 'no __newindex' flag NOT set: check. + |. li AT, LJ_TSTR + |6: + | load_got lj_tab_newkey + | sw STR:RC, LO(CARG3) + | sw AT, HI(CARG3) + | sw BASE, L->base + | move CARG2, TAB:RB + | sw PC, SAVE_PC + | call_intern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k + |. move CARG1, L + | // Returns TValue *. + | lw BASE, L->base + | b <3 // No 2nd write barrier needed. + |. sdc1 f20, 0(CRET1) + | + |7: // Possible table write barrier for the value. Skip valiswhite check. + | barrierback TAB:RB, TMP3, TMP0, <3 + break; + case BC_TSETB: + | // RA = src*8, RB = table*8, RC = index*8 + | decode_RB8a RB, INS + | decode_RB8b RB + | addu CARG2, BASE, RB + | decode_RDtoRC8 RC, RD + | lw CARG1, HI(CARG2) + | li AT, LJ_TTAB + | lw TAB:RB, LO(CARG2) + | addu RA, BASE, RA + | bne CARG1, AT, ->vmeta_tsetb + |. srl TMP0, RC, 3 + | lw TMP1, TAB:RB->asize + | lw TMP2, TAB:RB->array + | sltu AT, TMP0, TMP1 + | beqz AT, ->vmeta_tsetb + |. addu RC, TMP2, RC + | lw TMP1, HI(RC) + | lbu TMP3, TAB:RB->marked + | beq TMP1, TISNIL, >5 + |. ldc1 f0, 0(RA) + |1: + | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | bnez AT, >7 + |. sdc1 f0, 0(RC) + |2: + | ins_next + | + |5: // Check for __newindex if previous value is nil. + | lw TAB:TMP2, TAB:RB->metatable + | beqz TAB:TMP2, <1 // No metatable: done. + |. nop + | lbu TMP1, TAB:TMP2->nomm + | andi TMP1, TMP1, 1<vmeta_tsetb // Caveat: preserve TMP0! + |. nop + | + |7: // Possible table write barrier for the value. Skip valiswhite check. + | barrierback TAB:RB, TMP3, TMP0, <2 + break; + + case BC_TSETM: + | // RA = base*8 (table at base-1), RD = num_const*8 (start index) + | addu RA, BASE, RA + |1: + | addu TMP3, KBASE, RD + | lw TAB:CARG2, -8+LO(RA) // Guaranteed to be a table. + | addiu TMP0, MULTRES, -8 + | lw TMP3, LO(TMP3) // Integer constant is in lo-word. + | beqz TMP0, >4 // Nothing to copy? + |. srl CARG3, TMP0, 3 + | addu CARG3, CARG3, TMP3 + | lw TMP2, TAB:CARG2->asize + | sll TMP1, TMP3, 3 + | lbu TMP3, TAB:CARG2->marked + | lw CARG1, TAB:CARG2->array + | sltu AT, TMP2, CARG3 + | bnez AT, >5 + |. addu TMP2, RA, TMP0 + | addu TMP1, TMP1, CARG1 + | andi TMP0, TMP3, LJ_GC_BLACK // isblack(table) + |3: // Copy result slots to table. + | ldc1 f0, 0(RA) + | addiu RA, RA, 8 + | sltu AT, RA, TMP2 + | sdc1 f0, 0(TMP1) + | bnez AT, <3 + |. addiu TMP1, TMP1, 8 + | bnez TMP0, >7 + |. nop + |4: + | ins_next + | + |5: // Need to resize array part. + | load_got lj_tab_reasize + | sw BASE, L->base + | sw PC, SAVE_PC + | move BASE, RD + | call_intern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize) + |. move CARG1, L + | // Must not reallocate the stack. + | move RD, BASE + | b <1 + |. lw BASE, L->base // Reload BASE for lack of a saved register. + | + |7: // Possible table write barrier for any value. Skip valiswhite check. + | barrierback TAB:CARG2, TMP3, TMP0, <4 + break; + + /* -- Calls and vararg handling ----------------------------------------- */ + + case BC_CALLM: + | // RA = base*8, (RB = (nresults+1)*8,) RC = extra_nargs*8 + | decode_RDtoRC8 NARGS8:RC, RD + | b ->BC_CALL_Z + |. addu NARGS8:RC, NARGS8:RC, MULTRES + break; + case BC_CALL: + | // RA = base*8, (RB = (nresults+1)*8,) RC = (nargs+1)*8 + | decode_RDtoRC8 NARGS8:RC, RD + |->BC_CALL_Z: + | move TMP2, BASE + | addu BASE, BASE, RA + | li AT, LJ_TFUNC + | lw TMP0, HI(BASE) + | lw LFUNC:RB, LO(BASE) + | addiu BASE, BASE, 8 + | bne TMP0, AT, ->vmeta_call + |. addiu NARGS8:RC, NARGS8:RC, -8 + | ins_call + break; + + case BC_CALLMT: + | // RA = base*8, (RB = 0,) RC = extra_nargs*8 + | addu NARGS8:RD, NARGS8:RD, MULTRES // BC_CALLT gets RC from RD. + | // Fall through. Assumes BC_CALLT follows. + break; + case BC_CALLT: + | // RA = base*8, (RB = 0,) RC = (nargs+1)*8 + | addu RA, BASE, RA + | li AT, LJ_TFUNC + | lw TMP0, HI(RA) + | lw LFUNC:RB, LO(RA) + | move NARGS8:RC, RD + | lw TMP1, FRAME_PC(BASE) + | addiu RA, RA, 8 + | bne TMP0, AT, ->vmeta_callt + |. addiu NARGS8:RC, NARGS8:RC, -8 + |->BC_CALLT_Z: + | andi TMP0, TMP1, FRAME_TYPE // Caveat: preserve TMP0 until the 'or'. + | lbu TMP3, LFUNC:RB->ffid + | bnez TMP0, >7 + |. xori TMP2, TMP1, FRAME_VARG + |1: + | sw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC. + | sltiu AT, TMP3, 2 // (> FF_C) Calling a fast function? + | move TMP2, BASE + | beqz NARGS8:RC, >3 + |. move TMP3, NARGS8:RC + |2: + | ldc1 f0, 0(RA) + | addiu RA, RA, 8 + | addiu TMP3, TMP3, -8 + | sdc1 f0, 0(TMP2) + | bnez TMP3, <2 + |. addiu TMP2, TMP2, 8 + |3: + | or TMP0, TMP0, AT + | beqz TMP0, >5 + |. nop + |4: + | ins_callt + | + |5: // Tailcall to a fast function with a Lua frame below. + | lw INS, -4(TMP1) + | decode_RA8a RA, INS + | decode_RA8b RA + | subu TMP1, BASE, RA + | lw LFUNC:TMP1, -8+FRAME_FUNC(TMP1) + | lw TMP1, LFUNC:TMP1->pc + | b <4 + |. lw KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE. + | + |7: // Tailcall from a vararg function. + | andi AT, TMP2, FRAME_TYPEP + | bnez AT, <1 // Vararg frame below? + |. subu TMP2, BASE, TMP2 // Relocate BASE down. + | move BASE, TMP2 + | lw TMP1, FRAME_PC(TMP2) + | b <1 + |. andi TMP0, TMP1, FRAME_TYPE + break; + + case BC_ITERC: + | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 ((2+1)*8)) + | move TMP2, BASE + | addu BASE, BASE, RA + | li AT, LJ_TFUNC + | lw TMP1, -24+HI(BASE) + | lw LFUNC:RB, -24+LO(BASE) + | ldc1 f2, -8(BASE) + | ldc1 f0, -16(BASE) + | sw TMP1, HI(BASE) // Copy callable. + | sw LFUNC:RB, LO(BASE) + | sdc1 f2, 16(BASE) // Copy control var. + | sdc1 f0, 8(BASE) // Copy state. + | addiu BASE, BASE, 8 + | bne TMP1, AT, ->vmeta_call + |. li NARGS8:RC, 16 // Iterators get 2 arguments. + | ins_call + break; + + case BC_ITERN: + | // RA = base*8, (RB = (nresults+1)*8, RC = (nargs+1)*8 (2+1)*8) +#if LJ_HASJIT + | // NYI: add hotloop, record BC_ITERN. +#endif + | addu RA, BASE, RA + | lw TAB:RB, -16+LO(RA) + | lw RC, -8+LO(RA) // Get index from control var. + | lw TMP0, TAB:RB->asize + | lw TMP1, TAB:RB->array + | addiu PC, PC, 4 + |1: // Traverse array part. + | sltu AT, RC, TMP0 + | beqz AT, >5 // Index points after array part? + |. sll TMP3, RC, 3 + | addu TMP3, TMP1, TMP3 + | lw TMP2, HI(TMP3) + | ldc1 f0, 0(TMP3) + | mtc1 RC, f2 + | lhu RD, -4+OFS_RD(PC) + | beq TMP2, TISNIL, <1 // Skip holes in array part. + |. addiu RC, RC, 1 + | cvt.d.w f2, f2 + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | sdc1 f0, 8(RA) + | decode_RD4b RD + | addu RD, RD, TMP3 + | sw RC, -8+LO(RA) // Update control var. + | addu PC, PC, RD + | sdc1 f2, 0(RA) + |3: + | ins_next + | + |5: // Traverse hash part. + | lw TMP1, TAB:RB->hmask + | subu RC, RC, TMP0 + | lw TMP2, TAB:RB->node + |6: + | sltu AT, TMP1, RC // End of iteration? Branch to ITERL+1. + | bnez AT, <3 + |. sll TMP3, RC, 5 + | sll RB, RC, 3 + | subu TMP3, TMP3, RB + | addu NODE:TMP3, TMP3, TMP2 + | lw RB, HI(NODE:TMP3) + | ldc1 f0, 0(NODE:TMP3) + | lhu RD, -4+OFS_RD(PC) + | beq RB, TISNIL, <6 // Skip holes in hash part. + |. addiu RC, RC, 1 + | ldc1 f2, NODE:TMP3->key + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | sdc1 f0, 8(RA) + | addu RC, RC, TMP0 + | decode_RD4b RD + | addu RD, RD, TMP3 + | sdc1 f2, 0(RA) + | addu PC, PC, RD + | b <3 + |. sw RC, -8+LO(RA) // Update control var. + break; + + case BC_ISNEXT: + | // RA = base*8, RD = target (points to ITERN) + | addu RA, BASE, RA + | lw TMP0, -24+HI(RA) + | lw CFUNC:TMP1, -24+LO(RA) + | lw TMP2, -16+HI(RA) + | lw TMP3, -8+HI(RA) + | li AT, LJ_TFUNC + | bne TMP0, AT, >5 + |. addiu TMP2, TMP2, -LJ_TTAB + | lbu TMP1, CFUNC:TMP1->ffid + | addiu TMP3, TMP3, -LJ_TNIL + | srl TMP0, RD, 1 + | or TMP2, TMP2, TMP3 + | addiu TMP1, TMP1, -FF_next_N + | addu TMP0, PC, TMP0 + | or TMP1, TMP1, TMP2 + | bnez TMP1, >5 + |. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | addu PC, TMP0, TMP2 + | sw r0, -8+LO(RA) // Initialize control var. + |1: + | ins_next + |5: // Despecialize bytecode if any of the checks fail. + | li TMP3, BC_JMP + | li TMP1, BC_ITERC + | sb TMP3, -4+OFS_OP(PC) + | addu PC, TMP0, TMP2 + | b <1 + |. sb TMP1, OFS_OP(PC) + break; + + case BC_VARG: + | // RA = base*8, RB = (nresults+1)*8, RC = numparams*8 + | lw TMP0, FRAME_PC(BASE) + | decode_RDtoRC8 RC, RD + | decode_RB8a RB, INS + | addu RC, BASE, RC + | decode_RB8b RB + | addu RA, BASE, RA + | addiu RC, RC, FRAME_VARG + | addu TMP2, RA, RB + | addiu TMP3, BASE, -8 // TMP3 = vtop + | subu RC, RC, TMP0 // RC = vbase + | // Note: RC may now be even _above_ BASE if nargs was < numparams. + | beqz RB, >5 // Copy all varargs? + |. subu TMP1, TMP3, RC + | addiu TMP2, TMP2, -16 + |1: // Copy vararg slots to destination slots. + | lw CARG1, HI(RC) + | sltu AT, RC, TMP3 + | lw CARG2, LO(RC) + | addiu RC, RC, 8 + | movz CARG1, TISNIL, AT + | sw CARG1, HI(RA) + | sw CARG2, LO(RA) + | sltu AT, RA, TMP2 + | bnez AT, <1 + |. addiu RA, RA, 8 + |3: + | ins_next + | + |5: // Copy all varargs. + | lw TMP0, L->maxstack + | blez TMP1, <3 // No vararg slots? + |. li MULTRES, 8 // MULTRES = (0+1)*8 + | addu TMP2, RA, TMP1 + | sltu AT, TMP0, TMP2 + | bnez AT, >7 + |. addiu MULTRES, TMP1, 8 + |6: + | ldc1 f0, 0(RC) + | addiu RC, RC, 8 + | sdc1 f0, 0(RA) + | sltu AT, RC, TMP3 + | bnez AT, <6 // More vararg slots? + |. addiu RA, RA, 8 + | b <3 + |. nop + | + |7: // Grow stack for varargs. + | load_got lj_state_growstack + | sw RA, L->top + | subu RA, RA, BASE + | sw BASE, L->base + | subu BASE, RC, BASE // Need delta, because BASE may change. + | sw PC, SAVE_PC + | srl CARG2, TMP1, 3 + | call_intern lj_state_growstack // (lua_State *L, int n) + |. move CARG1, L + | move RC, BASE + | lw BASE, L->base + | addu RA, BASE, RA + | addu RC, BASE, RC + | b <6 + |. addiu TMP3, BASE, -8 + break; + + /* -- Returns ----------------------------------------------------------- */ + + case BC_RETM: + | // RA = results*8, RD = extra_nresults*8 + | addu RD, RD, MULTRES // MULTRES >= 8, so RD >= 8. + | // Fall through. Assumes BC_RET follows. + break; + + case BC_RET: + | // RA = results*8, RD = (nresults+1)*8 + | lw PC, FRAME_PC(BASE) + | addu RA, BASE, RA + | move MULTRES, RD + |1: + | andi TMP0, PC, FRAME_TYPE + | bnez TMP0, ->BC_RETV_Z + |. xori TMP1, PC, FRAME_VARG + | + |->BC_RET_Z: + | // BASE = base, RA = resultptr, RD = (nresults+1)*8, PC = return + | lw INS, -4(PC) + | addiu TMP2, BASE, -8 + | addiu RC, RD, -8 + | decode_RA8a TMP0, INS + | decode_RB8a RB, INS + | decode_RA8b TMP0 + | decode_RB8b RB + | addu TMP3, TMP2, RB + | beqz RC, >3 + |. subu BASE, TMP2, TMP0 + |2: + | ldc1 f0, 0(RA) + | addiu RA, RA, 8 + | addiu RC, RC, -8 + | sdc1 f0, 0(TMP2) + | bnez RC, <2 + |. addiu TMP2, TMP2, 8 + |3: + | addiu TMP3, TMP3, -8 + |5: + | sltu AT, TMP2, TMP3 + | bnez AT, >6 + |. lw LFUNC:TMP1, FRAME_FUNC(BASE) + | ins_next1 + | lw TMP1, LFUNC:TMP1->pc + | lw KBASE, PC2PROTO(k)(TMP1) + | ins_next2 + | + |6: // Fill up results with nil. + | sw TISNIL, HI(TMP2) + | b <5 + |. addiu TMP2, TMP2, 8 + | + |->BC_RETV_Z: // Non-standard return case. + | andi TMP2, TMP1, FRAME_TYPEP + | bnez TMP2, ->vm_return + |. nop + | // Return from vararg function: relocate BASE down. + | subu BASE, BASE, TMP1 + | b <1 + |. lw PC, FRAME_PC(BASE) + break; + + case BC_RET0: case BC_RET1: + | // RA = results*8, RD = (nresults+1)*8 + | lw PC, FRAME_PC(BASE) + | addu RA, BASE, RA + | move MULTRES, RD + | andi TMP0, PC, FRAME_TYPE + | bnez TMP0, ->BC_RETV_Z + |. xori TMP1, PC, FRAME_VARG + | + | lw INS, -4(PC) + | addiu TMP2, BASE, -8 + if (op == BC_RET1) { + | ldc1 f0, 0(RA) + } + | decode_RB8a RB, INS + | decode_RA8a RA, INS + | decode_RB8b RB + | decode_RA8b RA + if (op == BC_RET1) { + | sdc1 f0, 0(TMP2) + } + | subu BASE, TMP2, RA + |5: + | sltu AT, RD, RB + | bnez AT, >6 + |. lw LFUNC:TMP1, FRAME_FUNC(BASE) + | ins_next1 + | lw TMP1, LFUNC:TMP1->pc + | lw KBASE, PC2PROTO(k)(TMP1) + | ins_next2 + | + |6: // Fill up results with nil. + | addiu TMP2, TMP2, 8 + | addiu RD, RD, 8 + | b <5 + if (op == BC_RET1) { + |. sw TISNIL, HI(TMP2) + } else { + |. sw TISNIL, -8+HI(TMP2) + } + break; + + /* -- Loops and branches ------------------------------------------------ */ + + case BC_FORL: +#if LJ_HASJIT + | hotloop +#endif + | // Fall through. Assumes BC_IFORL follows. + break; + + case BC_JFORI: + case BC_JFORL: +#if !LJ_HASJIT + break; +#endif + case BC_FORI: + case BC_IFORL: + | // RA = base*8, RD = target (after end of loop or start of loop) + vk = (op == BC_IFORL || op == BC_JFORL); + | addu RA, BASE, RA + if (vk) { + | ldc1 f0, FORL_IDX*8(RA) + | ldc1 f4, FORL_STEP*8(RA) + | ldc1 f2, FORL_STOP*8(RA) + | lw TMP3, FORL_STEP*8+HI(RA) + | add.d f0, f0, f4 + | sdc1 f0, FORL_IDX*8(RA) + } else { + | lw TMP1, FORL_IDX*8+HI(RA) + | lw TMP3, FORL_STEP*8+HI(RA) + | lw TMP2, FORL_STOP*8+HI(RA) + | sltiu TMP1, TMP1, LJ_TISNUM + | sltiu TMP0, TMP3, LJ_TISNUM + | sltiu TMP2, TMP2, LJ_TISNUM + | and TMP1, TMP1, TMP0 + | and TMP1, TMP1, TMP2 + | ldc1 f0, FORL_IDX*8(RA) + | beqz TMP1, ->vmeta_for + |. ldc1 f2, FORL_STOP*8(RA) + } + if (op != BC_JFORL) { + | srl RD, RD, 1 + | lui TMP0, (-(BCBIAS_J*4 >> 16) & 65535) + } + | c.le.d 0, f0, f2 + | c.le.d 1, f2, f0 + | sdc1 f0, FORL_EXT*8(RA) + if (op == BC_JFORI) { + | li TMP1, 1 + | li TMP2, 1 + | lw INS, -4(PC) + | slt TMP3, TMP3, r0 + | movt TMP1, r0, 0 + | movt TMP2, r0, 1 + | addu PC, RD, TMP0 + | movn TMP1, TMP2, TMP3 + | decode_RD8a RD, INS + | bnez TMP1, =>BC_JLOOP + |. decode_RD8b RD + } else if (op == BC_JFORL) { + | li TMP1, 1 + | li TMP2, 1 + | slt TMP3, TMP3, r0 + | movf TMP1, r0, 0 + | movf TMP2, r0, 1 + | movn TMP1, TMP2, TMP3 + | bnez TMP1, =>BC_JLOOP + |. nop + } else { + | addu TMP1, RD, TMP0 + | slt TMP3, TMP3, r0 + | move TMP2, TMP1 + if (op == BC_FORI) { + | movt TMP1, r0, 0 + | movt TMP2, r0, 1 + } else { + | movf TMP1, r0, 0 + | movf TMP2, r0, 1 + } + | movn TMP1, TMP2, TMP3 + | addu PC, PC, TMP1 + } + | ins_next + break; + + case BC_ITERL: +#if LJ_HASJIT + | hotloop +#endif + | // Fall through. Assumes BC_IITERL follows. + break; + + case BC_JITERL: +#if !LJ_HASJIT + break; +#endif + case BC_IITERL: + | // RA = base*8, RD = target + | addu RA, BASE, RA + | lw TMP1, HI(RA) + | beq TMP1, TISNIL, >1 // Stop if iterator returned nil. + |. lw TMP2, LO(RA) + if (op == BC_JITERL) { + | sw TMP1, -8+HI(RA) + | b =>BC_JLOOP + |. sw TMP2, -8+LO(RA) + } else { + | branch_RD // Otherwise save control var + branch. + | sw TMP1, -8+HI(RA) + | sw TMP2, -8+LO(RA) + } + |1: + | ins_next + break; + + case BC_LOOP: + | // RA = base*8, RD = target (loop extent) + | // Note: RA/RD is only used by trace recorder to determine scope/extent + | // This opcode does NOT jump, it's only purpose is to detect a hot loop. +#if LJ_HASJIT + | hotloop +#endif + | // Fall through. Assumes BC_ILOOP follows. + break; + + case BC_ILOOP: + | // RA = base*8, RD = target (loop extent) + | ins_next + break; + + case BC_JLOOP: +#if LJ_HASJIT + | // RA = base*8 (ignored), RD = traceno*8 + | lw TMP1, DISPATCH_J(trace)(DISPATCH) + | srl RD, RD, 1 + | li AT, 0 + | addu TMP1, TMP1, RD + | // Traces on MIPS don't store the trace number, so use 0. + | sw AT, DISPATCH_GL(vmstate)(DISPATCH) + | lw TRACE:TMP2, 0(TMP1) + | sw BASE, DISPATCH_GL(jit_base)(DISPATCH) + | sw L, DISPATCH_GL(jit_L)(DISPATCH) + | lw TMP2, TRACE:TMP2->mcode + | jr TMP2 + |. addiu JGL, DISPATCH, GG_DISP2G+32768 +#endif + break; + + case BC_JMP: + | // RA = base*8 (only used by trace recorder), RD = target + | branch_RD + | ins_next + break; + + /* -- Function headers -------------------------------------------------- */ + + case BC_FUNCF: +#if LJ_HASJIT + | hotcall +#endif + case BC_FUNCV: /* NYI: compiled vararg functions. */ + | // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow. + break; + + case BC_JFUNCF: +#if !LJ_HASJIT + break; +#endif + case BC_IFUNCF: + | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8 + | lw TMP2, L->maxstack + | lbu TMP1, -4+PC2PROTO(numparams)(PC) + | lw KBASE, -4+PC2PROTO(k)(PC) + | sltu AT, TMP2, RA + | bnez AT, ->vm_growstack_l + |. sll TMP1, TMP1, 3 + if (op != BC_JFUNCF) { + | ins_next1 + } + |2: + | sltu AT, NARGS8:RC, TMP1 // Check for missing parameters. + | bnez AT, >3 + |. addu AT, BASE, NARGS8:RC + if (op == BC_JFUNCF) { + | decode_RD8a RD, INS + | b =>BC_JLOOP + |. decode_RD8b RD + } else { + | ins_next2 + } + | + |3: // Clear missing parameters. + | sw TISNIL, HI(AT) + | b <2 + |. addiu NARGS8:RC, NARGS8:RC, 8 + break; + + case BC_JFUNCV: +#if !LJ_HASJIT + break; +#endif + | NYI // NYI: compiled vararg functions + break; /* NYI: compiled vararg functions. */ + + case BC_IFUNCV: + | // BASE = new base, RA = BASE+framesize*8, RB = LFUNC, RC = nargs*8 + | addu TMP1, BASE, RC + | lw TMP2, L->maxstack + | addu TMP0, RA, RC + | sw LFUNC:RB, LO(TMP1) // Store copy of LFUNC. + | addiu TMP3, RC, 8+FRAME_VARG + | sltu AT, TMP0, TMP2 + | lw KBASE, -4+PC2PROTO(k)(PC) + | beqz AT, ->vm_growstack_l + |. sw TMP3, HI(TMP1) // Store delta + FRAME_VARG. + | lbu TMP2, -4+PC2PROTO(numparams)(PC) + | move RA, BASE + | move RC, TMP1 + | ins_next1 + | beqz TMP2, >3 + |. addiu BASE, TMP1, 8 + |1: + | lw TMP0, HI(RA) + | lw TMP3, LO(RA) + | sltu AT, RA, RC // Less args than parameters? + | move CARG1, TMP0 + | movz TMP0, TISNIL, AT // Clear missing parameters. + | movn CARG1, TISNIL, AT // Clear old fixarg slot (help the GC). + | sw TMP3, 8+LO(TMP1) + | addiu TMP2, TMP2, -1 + | sw TMP0, 8+HI(TMP1) + | addiu TMP1, TMP1, 8 + | sw CARG1, HI(RA) + | bnez TMP2, <1 + |. addiu RA, RA, 8 + |3: + | ins_next2 + break; + + case BC_FUNCC: + case BC_FUNCCW: + | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8 + if (op == BC_FUNCC) { + | lw CFUNCADDR, CFUNC:RB->f + } else { + | lw CFUNCADDR, DISPATCH_GL(wrapf)(DISPATCH) + } + | addu TMP1, RA, NARGS8:RC + | lw TMP2, L->maxstack + | addu RC, BASE, NARGS8:RC + | sw BASE, L->base + | sltu AT, TMP2, TMP1 + | sw RC, L->top + | li_vmstate C + if (op == BC_FUNCCW) { + | lw CARG2, CFUNC:RB->f + } + | bnez AT, ->vm_growstack_c // Need to grow stack. + |. move CARG1, L + | jalr CFUNCADDR // (lua_State *L [, lua_CFunction f]) + |. st_vmstate + | // Returns nresults. + | lw BASE, L->base + | sll RD, CRET1, 3 + | lw TMP1, L->top + | li_vmstate INTERP + | lw PC, FRAME_PC(BASE) // Fetch PC of caller. + | subu RA, TMP1, RD // RA = L->top - nresults*8 + | b ->vm_returnc + |. st_vmstate + break; + + /* ---------------------------------------------------------------------- */ + + default: + fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]); + exit(2); + break; + } +} + +static int build_backend(BuildCtx *ctx) +{ + int op; + + dasm_growpc(Dst, BC__MAX); + + build_subroutines(ctx); + + |.code_op + for (op = 0; op < BC__MAX; op++) + build_ins(ctx, (BCOp)op, op); + + return BC__MAX; +} + +/* Emit pseudo frame-info for all assembler functions. */ +static void emit_asm_debug(BuildCtx *ctx) +{ + int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code); + int i; + switch (ctx->mode) { + case BUILD_elfasm: + fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n"); + fprintf(ctx->fp, + ".Lframe0:\n" + "\t.4byte .LECIE0-.LSCIE0\n" + ".LSCIE0:\n" + "\t.4byte 0xffffffff\n" + "\t.byte 0x1\n" + "\t.string \"\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE0:\n\n"); + fprintf(ctx->fp, + ".LSFDE0:\n" + "\t.4byte .LEFDE0-.LASFDE0\n" + ".LASFDE0:\n" + "\t.4byte .Lframe0\n" + "\t.4byte .Lbegin\n" + "\t.4byte %d\n" + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x9f\n\t.sleb128 1\n" + "\t.byte 0x9e\n\t.sleb128 2\n", + fcofs, CFRAME_SIZE); + for (i = 23; i >= 16; i--) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); + for (i = 30; i >= 20; i -= 2) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE0:\n\n"); +#if LJ_HASFFI + fprintf(ctx->fp, + ".LSFDE1:\n" + "\t.4byte .LEFDE1-.LASFDE1\n" + ".LASFDE1:\n" + "\t.4byte .Lframe0\n" + "\t.4byte lj_vm_ffi_call\n" + "\t.4byte %d\n" + "\t.byte 0x9f\n\t.uleb128 1\n" + "\t.byte 0x90\n\t.uleb128 2\n" + "\t.byte 0xd\n\t.uleb128 0x10\n" + "\t.align 2\n" + ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); +#endif + fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n"); + fprintf(ctx->fp, + "\t.globl lj_err_unwind_dwarf\n" + ".Lframe1:\n" + "\t.4byte .LECIE1-.LSCIE1\n" + ".LSCIE1:\n" + "\t.4byte 0\n" + "\t.byte 0x1\n" + "\t.string \"zPR\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.uleb128 6\n" /* augmentation length */ + "\t.byte 0\n" + "\t.4byte lj_err_unwind_dwarf\n" + "\t.byte 0\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE1:\n\n"); + fprintf(ctx->fp, + ".LSFDE2:\n" + "\t.4byte .LEFDE2-.LASFDE2\n" + ".LASFDE2:\n" + "\t.4byte .LASFDE2-.Lframe1\n" + "\t.4byte .Lbegin\n" + "\t.4byte %d\n" + "\t.uleb128 0\n" /* augmentation length */ + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x9f\n\t.sleb128 1\n" + "\t.byte 0x9e\n\t.sleb128 2\n", + fcofs, CFRAME_SIZE); + for (i = 23; i >= 16; i--) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); + for (i = 30; i >= 20; i -= 2) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE2:\n\n"); +#if LJ_HASFFI + fprintf(ctx->fp, + ".Lframe2:\n" + "\t.4byte .LECIE2-.LSCIE2\n" + ".LSCIE2:\n" + "\t.4byte 0\n" + "\t.byte 0x1\n" + "\t.string \"zR\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.uleb128 1\n" /* augmentation length */ + "\t.byte 0\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE2:\n\n"); + fprintf(ctx->fp, + ".LSFDE3:\n" + "\t.4byte .LEFDE3-.LASFDE3\n" + ".LASFDE3:\n" + "\t.4byte .LASFDE3-.Lframe2\n" + "\t.4byte lj_vm_ffi_call\n" + "\t.4byte %d\n" + "\t.uleb128 0\n" /* augmentation length */ + "\t.byte 0x9f\n\t.uleb128 1\n" + "\t.byte 0x90\n\t.uleb128 2\n" + "\t.byte 0xd\n\t.uleb128 0x10\n" + "\t.align 2\n" + ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); +#endif + break; + default: + break; + } +} + diff --git a/src/buildvm_mips.h b/src/buildvm_mips.h new file mode 100644 index 00000000..948f7d49 --- /dev/null +++ b/src/buildvm_mips.h @@ -0,0 +1,7245 @@ +/* +** This file has been pre-processed with DynASM. +** http://luajit.org/dynasm.html +** DynASM version 1.3.0, DynASM mips version 1.3.0 +** DO NOT EDIT! The original file is in "buildvm_mips.dasc". +*/ + +#if DASM_VERSION != 10300 +#error "Version mismatch between DynASM and included encoding engine" +#endif + +#define DASM_SECTION_CODE_OP 0 +#define DASM_SECTION_CODE_SUB 1 +#define DASM_MAXSECTION 2 +static const unsigned int build_actionlist[6076] = { +0xff010001, +0xff060014, +0x32410000, +0xff090200, +0x10200000, +0xff050815, +0x240d0000, +0xff098200, +0x8dd20000, +0xff098200, +0x01c08021, +0xaeed0000, +0xff098200, +0x26f7fff8, +0xff060016, +0x324c0000, +0xff090200, +0x254a0008, +0x11800000, +0xff050817, +0x0140a821, +0xff060018, +0x240efff8, +0x39810000, +0xff090200, +0x024e7024, +0x14200000, +0xff050814, +0x020e7023, +0x254dfff8, +0xae8e0000, +0xff098200, +0x240c0000, +0xff098200, +0x8fae0078, +0x2610fff8, +0xae6c0000, +0xff098200, +0x11a00000, +0xff050802, +0x000e70c0, +0xff06000b, +0x25adfff8, +0xd6e00000, +0x26f70008, +0xf6000000, +0x15a00000, +0xff05080b, +0x26100008, +0xff06000c, +0x15ca0000, +0xff050806, +0xff06000d, +0xae900000, +0xff098200, +0xff060019, +0xff000000, +0x8fac0074, +0x00001021, +0xae8c0000, +0xff098200, +0xff06001a, +0x8fbf0000, +0xff098200, +0x8fbe0000, +0xff098200, +0xd7be0000, +0xff098200, +0x8fb70000, +0xff098200, +0x8fb60000, +0xff098200, +0xd7bc0000, +0xff098200, +0x8fb50000, +0xff098200, +0x8fb40000, +0xff098200, +0xd7ba0000, +0xff098200, +0x8fb30000, +0xff098200, +0x8fb20000, +0xff098200, +0xd7b80000, +0xff098200, +0x8fb10000, +0xff098200, +0x8fb00000, +0xff098200, +0xd7b60000, +0xff098200, +0xd7b40000, +0xff098200, +0x03e00008, +0x27bd0070, +0xff060010, +0x8e8d0000, +0xff098200, +0x01ca082a, +0x14200000, +0xff050807, +0x020d082a, +0x10200000, +0xff050808, +0x00000000, +0xae1e0000, +0xff098200, +0xff000000, +0x254a0008, +0x10000000, +0xff05080c, +0x26100008, +0xff060011, +0x014e6023, +0x020c6023, +0x10000000, +0xff05080d, +0x018e800b, +0xff060012, +0x8e790000, +0xff098200, +0x0140a821, +0x01c02821, +0x0320f809, +0x02802021, +0x8fae0078, +0x8e900000, +0xff098200, +0x02a05021, +0x10000000, +0xff05080c, +0x000e70c0, +0xff06001b, +0x0080e821, +0x00a01021, +0xff06001c, +0x8fb40070, +0x240c0000, +0xff098200, +0x8e8d0000, +0xff098200, +0x10000000, +0xff05081a, +0xadac0000, +0xff098200, +0xff06001d, +0x2401fffc, +0x0081e824, +0xff06001e, +0x8fb40070, +0x3c0f59c0, +0x241e0000, +0xff098200, +0x8e900000, +0xff098200, +0x8e930000, +0xff098200, +0x448ff000, +0x240d0000, +0xff098200, +0x240c0000, +0xff098200, +0x8e120000, +0xff098200, +0x4600f7a1, +0x2617fff8, +0x26730000, +0xff098200, +0xaeed0000, +0xff098200, +0xff000000, +0xae6c0000, +0xff098200, +0x10000000, +0xff050816, +0x240a0010, +0xff06001f, +0x10000000, +0xff050802, +0x24050000, +0xff098200, +0xff060020, +0x02094821, +0x02f0b823, +0xae900000, +0xff098200, +0x26520004, +0xae890000, +0xff098200, +0x001728c2, +0xff06000c, +0x8e790000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0x8e890000, +0xff098200, +0x8e080000, +0xff098200, +0x01304823, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff060021, +0x27bdff90, +0xafbf0000, +0xff098200, +0xafbe0000, +0xff098200, +0xf7be0000, +0xff098200, +0xafb70000, +0xff098200, +0xafb60000, +0xff098200, +0xf7bc0000, +0xff098200, +0xafb50000, +0xff098200, +0xafb40000, +0xff098200, +0xff000000, +0xf7ba0000, +0xff098200, +0xafb30000, +0xff098200, +0xafb20000, +0xff098200, +0xf7b80000, +0xff098200, +0xafb10000, +0xff098200, +0xafb00000, +0xff098200, +0xf7b60000, +0xff098200, +0xf7b40000, +0xff098200, +0x0080a021, +0x8e930000, +0xff098200, +0x00a08021, +0x928d0000, +0xff098200, +0xafb40070, +0x24120000, +0xff098200, +0x27ac0000, +0xff098200, +0x26730000, +0xff098200, +0xafa00078, +0xafa0007c, +0xae8c0000, +0xff098200, +0xafa00074, +0x11a00000, +0xff050803, +0xafa40014, +0x0200b821, +0x8e900000, +0xff098200, +0x8e8d0000, +0xff098200, +0x8e120000, +0xff098200, +0x3c0f59c0, +0x01b05023, +0x448ff000, +0xa2800000, +0xff098200, +0x4600f7a1, +0x240c0000, +0xff098200, +0x254a0008, +0xae6c0000, +0xff098200, +0x0140a821, +0x324c0000, +0xff090200, +0x11800000, +0xff050817, +0xff000000, +0x241e0000, +0xff098200, +0x10000000, +0xff050818, +0x00000000, +0xff060022, +0x27bdff90, +0xafbf0000, +0xff098200, +0xafbe0000, +0xff098200, +0xf7be0000, +0xff098200, +0xafb70000, +0xff098200, +0xafb60000, +0xff098200, +0xf7bc0000, +0xff098200, +0xafb50000, +0xff098200, +0xafb40000, +0xff098200, +0xf7ba0000, +0xff098200, +0xafb30000, +0xff098200, +0xafb20000, +0xff098200, +0xf7b80000, +0xff098200, +0xafb10000, +0xff098200, +0xafb00000, +0xff098200, +0xf7b60000, +0xff098200, +0xf7b40000, +0xff098200, +0xafa7007c, +0x10000000, +0xff050801, +0x24120000, +0xff098200, +0xff060023, +0x27bdff90, +0xafbf0000, +0xff098200, +0xff000000, +0xafbe0000, +0xff098200, +0xf7be0000, +0xff098200, +0xafb70000, +0xff098200, +0xafb60000, +0xff098200, +0xf7bc0000, +0xff098200, +0xafb50000, +0xff098200, +0xafb40000, +0xff098200, +0xf7ba0000, +0xff098200, +0xafb30000, +0xff098200, +0xafb20000, +0xff098200, +0xf7b80000, +0xff098200, +0xafb10000, +0xff098200, +0xafb00000, +0xff098200, +0xf7b60000, +0xff098200, +0xf7b40000, +0xff098200, +0x24120000, +0xff098200, +0xff06000b, +0x8c8d0000, +0xff098200, +0xafa60078, +0x0080a021, +0xafa40070, +0x00a08021, +0xae9d0000, +0xff098200, +0x8e930000, +0xff098200, +0xafa40014, +0xafad0074, +0x26730000, +0xff098200, +0xff06000d, +0x8e8e0000, +0xff098200, +0xff000000, +0x3c0f59c0, +0x8e8d0000, +0xff098200, +0x448ff000, +0x02509021, +0x01b04823, +0x024e9023, +0x4600f7a1, +0x240c0000, +0xff098200, +0x241e0000, +0xff098200, +0xae6c0000, +0xff098200, +0xff060024, +0x8e0c0000, +0xff098200, +0x24010000, +0xff098200, +0x15810000, +0xff050825, +0x8e080000, +0xff098200, +0xff060026, +0xae120000, +0xff098200, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff060027, +0x27bdff90, +0xafbf0000, +0xff098200, +0xafbe0000, +0xff098200, +0xf7be0000, +0xff098200, +0xafb70000, +0xff098200, +0xafb60000, +0xff098200, +0xf7bc0000, +0xff098200, +0xafb50000, +0xff098200, +0xafb40000, +0xff098200, +0xf7ba0000, +0xff098200, +0xafb30000, +0xff098200, +0xff000000, +0xafb20000, +0xff098200, +0xf7b80000, +0xff098200, +0xafb10000, +0xff098200, +0xafb00000, +0xff098200, +0xf7b60000, +0xff098200, +0xf7b40000, +0xff098200, +0x0080a021, +0x8c8c0000, +0xff098200, +0xafa40070, +0x8e8d0000, +0xff098200, +0xafa40014, +0x018d6023, +0x8e8d0000, +0xff098200, +0xae9d0000, +0xff098200, +0xafac0078, +0xafa0007c, +0x00e0c821, +0x00e0f809, +0xafad0074, +0x00408021, +0x8e930000, +0xff098200, +0x24120000, +0xff098200, +0x14400000, +0xff05080d, +0x26730000, +0xff098200, +0x10000000, +0xff050819, +0x00000000, +0xff060015, +0x8e0c0000, +0xff098200, +0x02004021, +0x01c08021, +0x8dcd0000, +0xff098200, +0xff000000, +0x2d810002, +0xff000000, +0x8d120000, +0xff098200, +0x02ea7021, +0x8dad0000, +0xff098200, +0xff000000, +0x14200000, +0xff050801, +0xff000000, +0xadde0000, +0xff098200, +0x01800008, +0x8db10000, +0xff098200, +0xff000000, +0xff06000b, +0x15800000, +0xff050828, +0x250dfff0, +0x10000000, +0xff050829, +0x01b04823, +0xff000000, +0xff06002a, +0x8e4bfffc, +0x2505fff0, +0xd6e00000, +0x000bad42, +0x000bb942, +0x32b507f8, +0x32f707f8, +0x02156821, +0xae900000, +0xff098200, +0x00ad3023, +0x15a50000, +0xff05082b, +0xf4a00000, +0x0217b821, +0x10000000, +0xff05082c, +0xf6e00000, +0xff06002d, +0x26660000, +0xff098200, +0x240c0000, +0xff098200, +0xacc90000, +0xff098200, +0x10000000, +0xff050801, +0xaccc0000, +0xff098200, +0xff06002e, +0x26650000, +0xff098200, +0x240c0000, +0xff098200, +0xaca80000, +0xff098200, +0x26660000, +0xff098200, +0xacac0000, +0xff098200, +0x240d0000, +0xff098200, +0xacc90000, +0xff098200, +0x10000000, +0xff050801, +0xaccd0000, +0xff098200, +0xff06002f, +0x448c0000, +0x46800021, +0x26660000, +0xff098200, +0xf4c00000, +0xff060030, +0xff06000b, +0xff000000, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x10400000, +0xff050803, +0x260d0000, +0xff098200, +0xd4400000, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000d, +0x8e900000, +0xff098200, +0xae120000, +0xff098200, +0x020d9023, +0x8e080000, +0xff098200, +0x10000000, +0xff050826, +0x24090010, +0xff060031, +0x26660000, +0xff098200, +0x240c0000, +0xff098200, +0xacc90000, +0xff098200, +0x10000000, +0xff050801, +0xaccc0000, +0xff098200, +0xff060032, +0x26650000, +0xff098200, +0x240c0000, +0xff098200, +0xaca80000, +0xff098200, +0x26660000, +0xff098200, +0xacac0000, +0xff098200, +0x240d0000, +0xff098200, +0xacc90000, +0xff098200, +0xff000000, +0x10000000, +0xff050801, +0xaccd0000, +0xff098200, +0xff060033, +0x448c0000, +0x46800021, +0x26660000, +0xff098200, +0xf4c00000, +0xff060034, +0xff06000b, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x10400000, +0xff050803, +0xd6e00000, +0x8e4b0000, +0x26520004, +0xf4400000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000d, +0x260d0000, +0xff098200, +0x8e900000, +0xff098200, +0xae120000, +0xff098200, +0x020d9023, +0x8e080000, +0xff098200, +0xf6000010, +0x10000000, +0xff050826, +0x24090018, +0xff060035, +0x8e790000, +0xff098200, +0x2652fffc, +0xae900000, +0xff098200, +0xafb20014, +0x316700ff, +0x0320f809, +0x02802021, +0xff06000d, +0x2c410002, +0x10200000, +0xff050836, +0x00027023, +0xff06000e, +0x964a0000, +0xff098200, +0x26520004, +0x3c0d0000, +0xff090200, +0xff000000, +0x000a5080, +0x014d5021, +0x014e5024, +0x024a9021, +0xff06002c, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff060037, +0x924d0000, +0xff098200, +0xd6e00000, +0x000d68c0, +0x020d6821, +0x10000000, +0xff05082c, +0xf5a00000, +0xff060038, +0x8eec0000, +0xff098200, +0x2d810000, +0xff098200, +0x10000000, +0xff05080e, +0x00017023, +0xff060039, +0x8eec0000, +0xff098200, +0x2d810000, +0xff098200, +0x10000000, +0xff05080e, +0x242effff, +0xff06003a, +0x8e790000, +0xff098200, +0x2652fffc, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x10000000, +0xff05080d, +0x00000000, +0xff06003b, +0xff000000, +0x8e790000, +0xff098200, +0x01602821, +0x2652fffc, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x10000000, +0xff05080d, +0x00000000, +0xff000000, +0xff06003c, +0x00c03821, +0xff06003d, +0x8e790000, +0xff098200, +0x316c00ff, +0xae900000, +0xff098200, +0xafb20014, +0x02e02821, +0xafac0010, +0x0320f809, +0x02802021, +0x10400000, +0xff05082c, +0x00000000, +0xff060036, +0x00506823, +0xac520000, +0xff098200, +0x02007021, +0x25b20000, +0xff098200, +0x00408021, +0x10000000, +0xff050824, +0x24090010, +0xff06003e, +0xff000000, +0x0080a821, +0xff000000, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0xff000000, +0x14400000, +0xff050836, +0x00000000, +0x10000000, +0xff05083f, +0x02a02021, +0xff000000, +0x10000000, +0xff050836, +0x00000000, +0xff000000, +0xff060025, +0x8e790000, +0xff098200, +0xae8e0000, +0xff098200, +0x2605fff8, +0xafb20014, +0x02093021, +0x0120a821, +0x0320f809, +0x02802021, +0x8e080000, +0xff098200, +0x26a90008, +0xae120000, +0xff098200, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff060040, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0x26e5fff8, +0xafb20014, +0x02e93021, +0x0120a821, +0x0320f809, +0x02802021, +0x8e0d0000, +0xff098200, +0x8ee80000, +0xff098200, +0x10000000, +0xff050841, +0x26a90008, +0xff060042, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0x02e02821, +0xafb20014, +0x0160a821, +0x0320f809, +0x02802021, +0xff000000, +0x32ac00ff, +0x24010000, +0xff098200, +0xff000000, +0x0015b942, +0x00155402, +0x32f707f8, +0xff000000, +0x11810000, +0xff070800, +0x000a50c0, +0x10000000, +0xff070800, +0x00000000, +0xff000000, +0x10000000, +0xff070800, +0x000a50c0, +0xff000000, +0xff060043, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x2617fff8, +0x8e120000, +0xff098200, +0x252a0008, +0x02e97021, +0xaee60000, +0xff098200, +0x260d0008, +0x120e0000, +0xff050845, +0xaee40000, +0xff098200, +0xff06000b, +0xd5a00000, +0xf5a0fff8, +0x15ae0000, +0xff05080b, +0x25ad0008, +0x10000000, +0xff050845, +0x00000000, +0xff060046, +0x8e060000, +0xff098200, +0x240d0000, +0xff098200, +0x11200000, +0xff050844, +0x2ccc0000, +0xff098200, +0x00cc680a, +0x01a06827, +0x000d68c0, +0x010d6821, +0x10000000, +0xff050847, +0xd5a00000, +0xff098200, +0xff060048, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0xff000000, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050806, +0x24010000, +0xff098200, +0xff06000b, +0x8c840000, +0xff098200, +0xff06000c, +0x8e690000, +0xff098200, +0x10800000, +0xff050849, +0x24060000, +0xff098200, +0x8c8c0000, +0xff098200, +0x24060000, +0xff098200, +0x8d2d0000, +0xff098200, +0x8c8e0000, +0xff098200, +0x01ac6824, +0x000d6140, +0x000d68c0, +0x018d6823, +0x01cd7021, +0x24010000, +0xff098200, +0xff06000d, +0x8dc70000, +0xff098200, +0x8dcc0000, +0xff098200, +0x8dcf0000, +0xff098200, +0x14e10000, +0xff050804, +0x8dc50000, +0xff098200, +0x11890000, +0xff050805, +0x8dcd0000, +0xff098200, +0xff06000e, +0xff000000, +0x11e00000, +0xff050849, +0x01e07021, +0x10000000, +0xff05080d, +0x00000000, +0xff06000f, +0x10be0000, +0xff050849, +0x00000000, +0x00a03021, +0x10000000, +0xff050849, +0x01a02021, +0xff060010, +0x10c10000, +0xff05080b, +0x2ccc0000, +0xff098200, +0x240d0000, +0xff098200, +0x00cc680a, +0x01a06827, +0x000d6880, +0x026d6821, +0x10000000, +0xff05080c, +0x8da40000, +0xff098200, +0xff06004a, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0x8e040000, +0xff098200, +0x8e050000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x24e70000, +0xff098200, +0x8c8d0000, +0xff098200, +0x908f0000, +0xff098200, +0x00ed0825, +0x14200000, +0xff050844, +0xff000000, +0x31e10000, +0xff090200, +0x10200000, +0xff050849, +0xac850000, +0xff098200, +0x8e6c0000, +0xff098200, +0x31ef0000, +0xff090200, +0xae640000, +0xff098200, +0xa08f0000, +0xff098200, +0x10000000, +0xff050849, +0xac8c0000, +0xff098200, +0xff06004b, +0x8e070000, +0xff098200, +0x2d210010, +0x8e050000, +0xff098200, +0x8e790000, +0xff098200, +0x24e70000, +0xff098200, +0x00270825, +0x14200000, +0xff050844, +0x26060008, +0x0320f809, +0x02802021, +0x10000000, +0xff050847, +0xd4400000, +0xff06004c, +0x8e040000, +0xff098200, +0x39210008, +0x2c840000, +0xff098200, +0x0001200b, +0x10800000, +0xff050844, +0xd6000000, +0x10000000, +0xff050847, +0x00000000, +0xff06004d, +0x11200000, +0xff050844, +0xff000000, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x10c10000, +0xff050849, +0x8e6d0000, +0xff098200, +0x2ccc0000, +0xff098200, +0x2dad0001, +0x018d6024, +0x11800000, +0xff050844, +0xae900000, +0xff098200, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0xafb20014, +0x8e790000, +0xff098200, +0x02802021, +0x0320f809, +0x02002821, +0x24060000, +0xff098200, +0x10000000, +0xff050849, +0x00402021, +0xff06004f, +0x8e040000, +0xff098200, +0x8e050000, +0xff098200, +0x11200000, +0xff050844, +0x02097021, +0x24010000, +0xff098200, +0xadde0000, +0xff098200, +0x14810000, +0xff050844, +0x8e120000, +0xff098200, +0x8e790000, +0xff098200, +0xff000000, +0xae900000, +0xff098200, +0xae900000, +0xff098200, +0x26060008, +0xafb20014, +0x0320f809, +0x02802021, +0x10400000, +0xff050849, +0x24060000, +0xff098200, +0xd6000008, +0x2617fff8, +0xd6020010, +0x240a0000, +0xff098200, +0xf6e00000, +0x10000000, +0xff050845, +0xf6e20008, +0xff060050, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e120000, +0xff098200, +0xff000000, +0x8c8e0000, +0xff098200, +0xd5000000, +0xff098200, +0x15c00000, +0xff050844, +0xff000000, +0xd5000000, +0xff098200, +0xff000000, +0x2617fff8, +0xae1e0000, +0xff098200, +0x240a0000, +0xff098200, +0x10000000, +0xff050845, +0xf6e00000, +0xff060051, +0x2d210010, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x8e070000, +0xff098200, +0x14200000, +0xff050844, +0xd60e0008, +0x24c60000, +0xff098200, +0x2ce10000, +0xff098200, +0x240c0001, +0x0006080b, +0x448c6000, +0x10200000, +0xff050844, +0x8e120000, +0xff098200, +0x46207024, +0x46806321, +0x8c8c0000, +0xff098200, +0x8c8d0000, +0xff098200, +0x440e0000, +0x2617fff8, +0x462c7380, +0x25ce0001, +0x01cc082b, +0x000e78c0, +0x01af7821, +0x10200000, +0xff050802, +0xf6ee0000, +0x8dee0000, +0xff098200, +0xd5e00000, +0xff06000b, +0x11de0000, +0xff050845, +0x240a0000, +0xff098200, +0x240a0000, +0xff098200, +0x10000000, +0xff050845, +0xf6e00008, +0xff06000c, +0x8c8c0000, +0xff098200, +0xff000000, +0x8e790000, +0xff098200, +0x11800000, +0xff050845, +0x240a0000, +0xff098200, +0x0320f809, +0x01c02821, +0x10400000, +0xff050845, +0x240a0000, +0xff098200, +0x8c4e0000, +0xff098200, +0x10000000, +0xff05080b, +0xd4400000, +0xff060052, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e120000, +0xff098200, +0xff000000, +0x8c8e0000, +0xff098200, +0xd5000000, +0xff098200, +0x15c00000, +0xff050844, +0xff000000, +0xd5000000, +0xff098200, +0xff000000, +0x2617fff8, +0xae000000, +0xff098200, +0xae000000, +0xff098200, +0x240a0000, +0xff098200, +0x10000000, +0xff050845, +0xf6e00000, +0xff060053, +0x926f0000, +0xff098200, +0x11200000, +0xff050844, +0x02007021, +0x26100008, +0x000f7802, +0xff0900a6, +0x31ef0001, +0x25f20000, +0xff098200, +0x10000000, +0xff050824, +0x2529fff8, +0xff060054, +0x2d210010, +0x8e070000, +0xff098200, +0x14200000, +0xff050844, +0xd60e0008, +0xd60c0000, +0x926d0000, +0xff098200, +0x24010000, +0xff098200, +0x02007021, +0x14e10000, +0xff050844, +0x26100010, +0x000f7802, +0xff0900a6, +0xf5ce0000, +0x31ef0001, +0xf5cc0008, +0x25f20000, +0xff098200, +0x10000000, +0xff050824, +0x2529fff0, +0xff060055, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0xff000000, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x908c0000, +0xff098200, +0x8c8d0000, +0xff098200, +0x8c850000, +0xff098200, +0x8c8e0000, +0xff098200, +0x258f0000, +0xff098200, +0x1de00000, +0xff050844, +0x01c57026, +0x15a00000, +0xff050844, +0x01cc0825, +0x8c8c0000, +0xff098200, +0x10200000, +0xff050844, +0x8e120000, +0xff098200, +0x00a97021, +0x018e082b, +0x14200000, +0xff050844, +0xafb20014, +0xae900000, +0xff098200, +0xff06000b, +0x26100008, +0x2529fff8, +0x25cefff8, +0xac8e0000, +0xff098200, +0x02096821, +0x00a03021, +0xae900000, +0xff098200, +0xff06000c, +0xd6000000, +0x020d082b, +0x10200000, +0xff050803, +0x26100008, +0xf4c00000, +0x10000000, +0xff05080c, +0x24c60008, +0xff06000d, +0x04110000, +0xff050821, +0x0080b821, +0xff06000e, +0xff000000, +0x8eee0000, +0xff098200, +0x2c410000, +0xff098200, +0x8eef0000, +0xff098200, +0x240c0000, +0xff098200, +0x8e900000, +0xff098200, +0xae6c0000, +0xff098200, +0x10200000, +0xff050808, +0x01ee5023, +0x8e8c0000, +0xff098200, +0x11400000, +0xff050806, +0x020a6821, +0x018d082b, +0x14200000, +0xff050809, +0x01ca7821, +0xaeee0000, +0xff098200, +0x02006821, +0xff06000f, +0xd5c00000, +0x25ce0008, +0x01cf082b, +0xf5a00000, +0x14200000, +0xff05080f, +0x25ad0008, +0xff060010, +0x324c0000, +0xff090200, +0x240d0000, +0xff098200, +0x2617fff8, +0xae0d0000, +0xff098200, +0x254a0010, +0xff060011, +0xafb20014, +0x11800000, +0xff050817, +0x0140a821, +0x10000000, +0xff050818, +0x00000000, +0xff060012, +0x25effff8, +0x240d0000, +0xff098200, +0xd5e00000, +0xaeef0000, +0xff098200, +0xff000000, +0x240a0000, +0xff098200, +0xae0d0000, +0xff098200, +0x2617fff8, +0xf6000000, +0x10000000, +0xff050811, +0x324c0000, +0xff090200, +0xff060013, +0x8e790000, +0xff098200, +0x000a28c2, +0x0320f809, +0x02802021, +0x10000000, +0xff05080e, +0x24020000, +0xff060056, +0x8d040000, +0xff098200, +0x908c0000, +0xff098200, +0x8c8d0000, +0xff098200, +0x8c850000, +0xff098200, +0x8c8e0000, +0xff098200, +0x258f0000, +0xff098200, +0x1de00000, +0xff050844, +0x01c57026, +0x15a00000, +0xff050844, +0x01cc0825, +0x8c8c0000, +0xff098200, +0x10200000, +0xff050844, +0x8e120000, +0xff098200, +0x00a97021, +0x018e082b, +0x14200000, +0xff050844, +0xafb20014, +0xae900000, +0xff098200, +0xff06000b, +0xac8e0000, +0xff098200, +0xff000000, +0x02096821, +0x00a03021, +0xae900000, +0xff098200, +0xff06000c, +0xd6000000, +0x020d082b, +0x10200000, +0xff050803, +0x26100008, +0xf4c00000, +0x10000000, +0xff05080c, +0x24c60008, +0xff06000d, +0x04110000, +0xff050821, +0x0080b821, +0xff06000e, +0x8eee0000, +0xff098200, +0x2c410000, +0xff098200, +0x8eef0000, +0xff098200, +0x240c0000, +0xff098200, +0x8e900000, +0xff098200, +0xae6c0000, +0xff098200, +0x10200000, +0xff050808, +0x01ee5023, +0x8e8c0000, +0xff098200, +0x11400000, +0xff050806, +0x020a6821, +0x018d082b, +0x14200000, +0xff050809, +0x01ca7821, +0xaeee0000, +0xff098200, +0x02006821, +0xff06000f, +0xd5c00000, +0x25ce0008, +0x01cf082b, +0xf5a00000, +0x14200000, +0xff05080f, +0x25ad0008, +0xff060010, +0x324c0000, +0xff090200, +0x0200b821, +0x254a0008, +0xff060011, +0xff000000, +0xafb20014, +0x11800000, +0xff050817, +0x0140a821, +0x10000000, +0xff050818, +0x00000000, +0xff060012, +0x8e790000, +0xff098200, +0x02e02821, +0x0320f809, +0x02802021, +0xff060013, +0x8e790000, +0xff098200, +0x000a28c2, +0x0320f809, +0x02802021, +0x10000000, +0xff05080e, +0x24020000, +0xff060057, +0x8e8c0000, +0xff098200, +0x02096821, +0xae900000, +0xff098200, +0x318c0000, +0xff090200, +0xae8d0000, +0xff098200, +0x11800000, +0xff050844, +0x24020000, +0xff098200, +0xae800000, +0xff098200, +0x10000000, +0xff05081a, +0xa2820000, +0xff098200, +0xff060058, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x46206005, +0xff060047, +0xff000000, +0x8e120000, +0xff098200, +0x2617fff8, +0x10000000, +0xff050859, +0xf600fff8, +0xff060049, +0x8e120000, +0xff098200, +0xae060000, +0xff098200, +0x2617fff8, +0xae040000, +0xff098200, +0xff060059, +0x240a0000, +0xff098200, +0xff060045, +0x324c0000, +0xff090200, +0x15800000, +0xff050818, +0x0140a821, +0x8e4bfffc, +0x000b4542, +0x310807f8, +0xff06000f, +0x0148082b, +0x14200000, +0xff050806, +0x000b6142, +0x318c07f8, +0x8e4b0000, +0x26520004, +0x02ec8023, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff060010, +0x02ea6821, +0x254a0008, +0x10000000, +0xff05080f, +0xadbe0000, +0xff098200, +0xff06005a, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x04110000, +0xff05085b, +0x00000000, +0x10000000, +0xff050847, +0xff000000, +0x00000000, +0xff06005c, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x04110000, +0xff05085d, +0x00000000, +0x10000000, +0xff050847, +0x00000000, +0xff06005e, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff06005f, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060060, +0x8e060000, +0xff098200, +0xff000000, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060061, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060062, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060063, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0xff000000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060064, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060065, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060066, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0xff000000, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060067, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060068, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff060069, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0x8e790000, +0xff098200, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x00000000, +0x0320f809, +0xd60c0000, +0x10000000, +0xff050847, +0x00000000, +0xff06006a, +0xff000000, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x8e790000, +0xff098200, +0x0320f809, +0x00000000, +0x10000000, +0xff050847, +0x00000000, +0xff06006b, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x8e790000, +0xff098200, +0x0320f809, +0x00000000, +0x10000000, +0xff050847, +0x00000000, +0xff06006c, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0xff000000, +0x018d6024, +0x11800000, +0xff050844, +0x8e790000, +0xff098200, +0x0320f809, +0x00000000, +0x10000000, +0xff050847, +0x00000000, +0xff06006d, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x46206004, +0x10000000, +0xff050847, +0x00000000, +0xff06006e, +0xff06006f, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0xd50e0000, +0xff098200, +0x10000000, +0xff050847, +0x462e6002, +0xff060070, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0xff000000, +0x018d6024, +0x11800000, +0xff050844, +0x462073a4, +0x8e790000, +0xff098200, +0x44067000, +0x0320f809, +0x00000000, +0x10000000, +0xff050847, +0x00000000, +0xff060071, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x8e790000, +0xff098200, +0x8e120000, +0xff098200, +0x0320f809, +0x26660000, +0xff098200, +0x8e6d0000, +0xff098200, +0x2617fff8, +0x448d7000, +0xf6e00000, +0x468073a1, +0xf6ee0008, +0x10000000, +0xff050845, +0x240a0000, +0xff098200, +0xff060072, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x8e790000, +0xff098200, +0x8e120000, +0xff098200, +0x0320f809, +0x2606fff8, +0x2617fff8, +0xf6000000, +0x10000000, +0xff050845, +0x240a0000, +0xff098200, +0xff060073, +0xff000000, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd6000000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x02097021, +0x260d0008, +0x11ae0000, +0xff050847, +0xff06000b, +0x8da60000, +0xff098200, +0xd5ac0000, +0x25ad0008, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x462c0034, +0x15ae0000, +0xff05080b, +0x46206011, +0x10000000, +0xff050847, +0x00000000, +0xff060074, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd6000000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x02097021, +0x260d0008, +0x11ae0000, +0xff050847, +0xff06000b, +0x8da60000, +0xff098200, +0xd5ac0000, +0x25ad0008, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x46206034, +0x15ae0000, +0xff05080b, +0x46206011, +0x10000000, +0xff050847, +0xff000000, +0x00000000, +0xff060075, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x00000000, +0x10000000, +0xff050876, +0x8c820000, +0xff098200, +0xff060077, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x39210008, +0x24c60000, +0xff098200, +0x00260825, +0x14200000, +0xff050844, +0x00000000, +0x8c8c0000, +0xff098200, +0x908d0000, +0xff098200, +0x2617fff8, +0x000c502b, +0x448d0000, +0x254a0001, +0x46800021, +0x8e120000, +0xff098200, +0x000a50c0, +0x10000000, +0xff050845, +0xf6e00000, +0xff060078, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0x8e060000, +0xff098200, +0xd60c0000, +0x24010008, +0x15210000, +0xff050844, +0xff000000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x24060001, +0x46206324, +0x27a50010, +0x2d810100, +0x440c6000, +0x10200000, +0xff050844, +0xafac0010, +0xff060079, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0x00402021, +0x10000000, +0xff050849, +0x24060000, +0xff098200, +0xff06007a, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0x2521fff0, +0x8e060000, +0xff098200, +0xd6000010, +0x8e0c0000, +0xff098200, +0x8e040000, +0xff098200, +0x04200000, +0xff050844, +0x8e050000, +0xff098200, +0xd6020008, +0x10200000, +0xff050801, +0x2407ffff, +0x46200024, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x44070000, +0xff06000b, +0x2ca10000, +0xff098200, +0xff000000, +0x10200000, +0xff050844, +0x24010000, +0xff098200, +0x462010a4, +0x15810000, +0xff050844, +0x8c850000, +0xff098200, +0x44061000, +0x00e0082a, +0x24ac0001, +0x00ec6821, +0x00c0782a, +0x01a1380b, +0x00cc6821, +0x01af300b, +0x240e0001, +0x00e0082a, +0x0006782a, +0x0001380b, +0x01cf300a, +0x00a7082a, +0x00a1380b, +0x00862821, +0x00e63023, +0x24a50000, +0xff098200, +0x04c10000, +0xff050879, +0x24c60001, +0xff06007b, +0x26640000, +0xff098200, +0x10000000, +0xff050849, +0x24060000, +0xff098200, +0xff06007c, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0x8e0c0000, +0xff098200, +0x2d210010, +0x8e070000, +0xff098200, +0x8e040000, +0xff098200, +0x258c0000, +0xff098200, +0xd6000008, +0x002c0825, +0x14200000, +0xff050844, +0x2ce10000, +0xff098200, +0x46200024, +0x10200000, +0xff050844, +0x8c8c0000, +0xff098200, +0x44060000, +0x8e6d0000, +0xff098200, +0xff000000, +0x24010001, +0x18c00000, +0xff05087b, +0x002c082b, +0x11800000, +0xff05087b, +0x01a6602b, +0x002c0825, +0x8e650000, +0xff098200, +0x14200000, +0xff050844, +0x908c0000, +0xff098200, +0x00a67021, +0xff06000b, +0x25ceffff, +0x00ae082b, +0x14200000, +0xff05080b, +0xa1cc0000, +0x10000000, +0xff050879, +0x00000000, +0xff06007d, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x11200000, +0xff050844, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e6d0000, +0xff098200, +0x8c860000, +0xff098200, +0x24840000, +0xff098200, +0x8e650000, +0xff098200, +0x01a6082b, +0x14200000, +0xff050844, +0x00867821, +0x00a63821, +0xff06000b, +0xff000000, +0x908d0000, +0x008f082b, +0x10200000, +0xff050879, +0x24840001, +0x24e7ffff, +0x10000000, +0xff05080b, +0xa0ed0000, +0xff06007e, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x11200000, +0xff050844, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e6d0000, +0xff098200, +0x8c860000, +0xff098200, +0x24840000, +0xff098200, +0x8e650000, +0xff098200, +0x01a6082b, +0x14200000, +0xff050844, +0x00867821, +0x00a03821, +0xff06000b, +0x908d0000, +0x008f082b, +0x10200000, +0xff050879, +0x25acffbf, +0x39ae0020, +0x2d81001a, +0x01c1680b, +0x24840001, +0xa0ed0000, +0x10000000, +0xff05080b, +0x24e70001, +0xff06007f, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0x018d0823, +0x04310000, +0xff05084e, +0xff000000, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x11200000, +0xff050844, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e6d0000, +0xff098200, +0x8c860000, +0xff098200, +0x24840000, +0xff098200, +0x8e650000, +0xff098200, +0x01a6082b, +0x14200000, +0xff050844, +0x00867821, +0x00a03821, +0xff06000b, +0x908d0000, +0x008f082b, +0x10200000, +0xff050879, +0x25acff9f, +0x39ae0020, +0x2d81001a, +0x01c1680b, +0x24840001, +0xa0ed0000, +0x10000000, +0xff05080b, +0x24e70001, +0xff060080, +0x11200000, +0xff050844, +0x8e060000, +0xff098200, +0x8e040000, +0xff098200, +0x24010000, +0xff098200, +0x14c10000, +0xff050844, +0x8e790000, +0xff098200, +0x0320f809, +0x00000000, +0x10000000, +0xff050876, +0x00000000, +0xff060081, +0x8e060000, +0xff098200, +0xff000000, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0x260d0008, +0x02097021, +0xff06000b, +0x8da70000, +0xff098200, +0x11ae0000, +0xff050876, +0xd5ac0000, +0x2ce10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44056000, +0x00451024, +0x10000000, +0xff05080b, +0x25ad0008, +0xff060082, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0x260d0008, +0x02097021, +0xff06000b, +0x8da70000, +0xff098200, +0x11ae0000, +0xff050876, +0xd5ac0000, +0x2ce10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44056000, +0x00451025, +0x10000000, +0xff05080b, +0x25ad0008, +0xff060083, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xff000000, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0x260d0008, +0x02097021, +0xff06000b, +0x8da70000, +0xff098200, +0x11ae0000, +0xff050876, +0xd5ac0000, +0x2ce10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44056000, +0x00451026, +0x10000000, +0xff05080b, +0x25ad0008, +0xff060084, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0x00026602, +0x00027202, +0x00026e00, +0x31ceff00, +0x018d6025, +0x3042ff00, +0x018e6025, +0x00021200, +0x10000000, +0xff050876, +0x01821025, +0xff060085, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0x10000000, +0xff050876, +0x00401027, +0xff060086, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0xff000000, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x463e6300, +0x463e7380, +0x44046000, +0x44057000, +0x10000000, +0xff050876, +0x00a41004, +0xff060087, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x463e6300, +0x463e7380, +0x44046000, +0x44057000, +0x10000000, +0xff050876, +0x00a41006, +0xff060088, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x463e6300, +0x463e7380, +0x44046000, +0x44057000, +0x10000000, +0xff050876, +0x00a41007, +0xff060089, +0x2d210010, +0x8e060000, +0xff098200, +0xff000000, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x463e6300, +0x463e7380, +0x44046000, +0x44057000, +0x24010020, +0x00256023, +0x00a42804, +0x01842006, +0x10000000, +0xff050876, +0x00851025, +0xff06008a, +0x2d210010, +0x8e060000, +0xff098200, +0x14200000, +0xff050844, +0x8e070000, +0xff098200, +0xd60c0000, +0xd60e0008, +0x2ccc0000, +0xff098200, +0x2ced0000, +0xff098200, +0x018d6024, +0x11800000, +0xff050844, +0x463e6300, +0x463e7380, +0x44046000, +0x44057000, +0x24010020, +0x00256023, +0x00a42806, +0x01842004, +0x10000000, +0xff050876, +0x00851025, +0xff06008b, +0x8e060000, +0xff098200, +0x11200000, +0xff050844, +0xd60c0000, +0x2cc10000, +0xff098200, +0x10200000, +0xff050844, +0x463e6300, +0x44026000, +0xff060076, +0x44820000, +0x10000000, +0xff050847, +0x46800021, +0xff060044, +0x8d0f0000, +0xff098200, +0xff000000, +0x02096821, +0x8e120000, +0xff098200, +0x25ac0000, +0xff098200, +0x8e8e0000, +0xff098200, +0xafb20014, +0x01cc082b, +0xae900000, +0xff098200, +0xae8d0000, +0xff098200, +0x14200000, +0xff050805, +0x01e0c821, +0x01e0f809, +0x02802021, +0x8e900000, +0xff098200, +0x000250c0, +0x1c400000, +0xff050845, +0x2617fff8, +0xff06000b, +0x8e8c0000, +0xff098200, +0x8e080000, +0xff098200, +0x14400000, +0xff050829, +0x01904823, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff060029, +0x324c0000, +0xff090200, +0x2401fffc, +0x15800000, +0xff050803, +0x02416824, +0x924d0000, +0xff098200, +0x000d68c0, +0xff06000d, +0x10000000, +0xff050824, +0x020d7023, +0xff06000f, +0x8e790000, +0xff098200, +0x24050000, +0xff098200, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0xff000000, +0x10000000, +0xff05080b, +0x24020000, +0xff06004e, +0x03e0a821, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0x02096021, +0xafb20014, +0xae8c0000, +0xff098200, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0x02a0f821, +0x8e8c0000, +0xff098200, +0x8e080000, +0xff098200, +0x03e00008, +0x01904823, +0xff06008c, +0xff000000, +0x926f0000, +0xff098200, +0x31e10000, +0xff090200, +0x14200000, +0xff050805, +0x8e6e0000, +0xff098200, +0x31e10000, +0xff090200, +0x14200000, +0xff050801, +0x25ceffff, +0x31e10000, +0xff090200, +0x10200000, +0xff050801, +0x00000000, +0x10000000, +0xff050801, +0xae6e0000, +0xff098200, +0xff000000, +0xff06008d, +0x926f0000, +0xff098200, +0x31e10000, +0xff090200, +0x10200000, +0xff050801, +0xff06000f, +0x8d810000, +0xff098200, +0x00200008, +0x00000000, +0xff06008e, +0x926f0000, +0xff098200, +0x8e6e0000, +0xff098200, +0x31e10000, +0xff090200, +0x14200000, +0xff05080f, +0x31e10000, +0xff090200, +0x10200000, +0xff05080f, +0x25ceffff, +0x11c00000, +0xff050801, +0xae6e0000, +0xff098200, +0x31e10000, +0xff090200, +0x10200000, +0xff05080f, +0xff06000b, +0x8e790000, +0xff098200, +0xafb50010, +0x02402821, +0xae900000, +0xff098200, +0x0320f809, +0x02802021, +0xff06000d, +0x8e900000, +0xff098200, +0xff06000e, +0xff000000, +0x8e4bfffc, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0xff098200, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06008f, +0x26520004, +0x10000000, +0xff05080e, +0x8d150000, +0xff098200, +0xff060090, +0xff000000, +0xf0f0f0f0, +0xff000000, +0xff060091, +0xff000000, +0x10000000, +0xff050801, +0xff000000, +0x02402821, +0xff060092, +0xff000000, +0x36450001, +0xff06000b, +0xff000000, +0x8e790000, +0xff098200, +0x02096021, +0xafb20014, +0xae900000, +0xff098200, +0x02f0b823, +0xae8c0000, +0xff098200, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0x8e8c0000, +0xff098200, +0xafa00014, +0x01904823, +0x0217b821, +0x8e080000, +0xff098200, +0x00400008, +0x8e4bfffc, +0xff060093, +0xff000000, +0xf0f0f0f0, +0xff000000, +0xff060094, +0xff000000, +0xf0f0f0f0, +0xff000000, +0xff06005b, +0x3c0c4330, +0x44802000, +0x448c2800, +0x46206085, +0x44016800, +0x46241034, +0x46241000, +0x45000000, +0xff050801, +0x46240001, +0x0020082a, +0x3c0c3ff0, +0x46200087, +0x448c2800, +0x46211013, +0x46206034, +0x46240081, +0x03e00008, +0x46211011, +0xff06000b, +0x03e00008, +0x46206006, +0xff06005d, +0x3c0c4330, +0x44802000, +0x448c2800, +0x46206085, +0x44016800, +0x46241034, +0x46241000, +0x45000000, +0xff050801, +0x46240001, +0x0020082a, +0x3c0cbff0, +0x46200087, +0x448c2800, +0x46211013, +0x462c0034, +0x46240081, +0x03e00008, +0x46211011, +0xff06000b, +0x03e00008, +0x46206006, +0xff060095, +0xff000000, +0x3c0c4330, +0x44802000, +0x448c2800, +0x46206085, +0x44016800, +0x46241034, +0x46241000, +0x45000000, +0xff050801, +0x46240001, +0x0020082a, +0x3c0c3ff0, +0x448c2800, +0x46201034, +0x46240081, +0x46211011, +0x46200087, +0x03e00008, +0x46211013, +0xff06000b, +0x03e00008, +0x46206006, +0xff000000, +0xff060096, +0xff000000, +0x27bdff90, +0xafbf0000, +0xff098200, +0xafbe0000, +0xff098200, +0xf7be0000, +0xff098200, +0xafb70000, +0xff098200, +0xafb60000, +0xff098200, +0xf7bc0000, +0xff098200, +0xafb50000, +0xff098200, +0xafb40000, +0xff098200, +0xf7ba0000, +0xff098200, +0xafb30000, +0xff098200, +0xafb20000, +0xff098200, +0xf7b80000, +0xff098200, +0xafb10000, +0xff098200, +0xafb00000, +0xff098200, +0xf7b60000, +0xff098200, +0xf7b40000, +0xff098200, +0x8c520000, +0xff098200, +0x24530000, +0xff098200, +0x8e790000, +0xff098200, +0xae410000, +0xff098200, +0xae440000, +0xff098200, +0xae450000, +0xff098200, +0xf64c0000, +0xff098200, +0xff000000, +0xae460000, +0xff098200, +0xae470000, +0xff098200, +0xf64e0000, +0xff098200, +0x27ac0000, +0xff098200, +0xae4c0000, +0xff098200, +0xafa00014, +0x03a02821, +0x0320f809, +0x02402021, +0x8c500000, +0xff098200, +0x8c490000, +0xff098200, +0x0040a021, +0x3c0f59c0, +0x8e080000, +0xff098200, +0x448ff000, +0x240c0000, +0xff098200, +0x241e0000, +0xff098200, +0x01304823, +0xae6c0000, +0xff098200, +0x4600f7a1, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff000000, +0xff060028, +0xff000000, +0x8e790000, +0xff098200, +0x8e720000, +0xff098200, +0xae900000, +0xff098200, +0xae880000, +0xff098200, +0xae540000, +0xff098200, +0x02e02821, +0x0320f809, +0x02402021, +0x8e420000, +0xff098200, +0xd6400000, +0xff098200, +0x8e430000, +0xff098200, +0x10000000, +0xff05081a, +0xd6420000, +0xff098200, +0xff000000, +0xff060097, +0xff000000, +0x8c8d0000, +0xff098200, +0x90850000, +0xff098200, +0x03a07021, +0x03ade823, +0xaddffffc, +0x00052880, +0xadd0fff8, +0xadc4fff4, +0x01c08021, +0x248d0000, +0xff098200, +0x27ae0010, +0x10a00000, +0xff050802, +0x01a57821, +0xff06000b, +0x8dac0000, +0x25ad0004, +0x01af082b, +0xadcc0000, +0x14200000, +0xff05080b, +0x25ce0004, +0xff06000c, +0x8c990000, +0xff098200, +0x8c850000, +0xff098200, +0x8c860000, +0xff098200, +0x8c870000, +0xff098200, +0xd48c0000, +0xff098200, +0xd48e0000, +0xff098200, +0x0320f809, +0x8c840000, +0xff098200, +0x8e0dfff4, +0x8e0efff8, +0x8e1ffffc, +0xada20000, +0xff098200, +0xada30000, +0xff098200, +0xf5a00000, +0xff098200, +0xf5a20000, +0xff098200, +0x0200e821, +0x03e00008, +0x01c08021, +0xff000000, +0xff080000, +0xff000000, +0x02172821, +0x020a3021, +0x8cac0000, +0xff098200, +0x8ccd0000, +0xff098200, +0xd4a00000, +0xd4c20000, +0x2d8c0000, +0xff098200, +0x2dad0000, +0xff098200, +0x964e0000, +0xff098200, +0x018d6024, +0x26520004, +0x11800000, +0xff050835, +0x3c0d0000, +0xff090200, +0x000e7080, +0x01cd7021, +0xff000000, +0x46220034, +0xff000000, +0x46220036, +0xff000000, +0x00007001, +0xff000000, +0x00017001, +0xff000000, +0x024e9021, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x0217b821, +0x26520004, +0x8eec0000, +0xff098200, +0xd6e00000, +0x020a5021, +0x964e0000, +0xff098200, +0x8d4d0000, +0xff098200, +0xd5420000, +0x3c0f0000, +0xff090200, +0x2d810000, +0xff098200, +0x2da40000, +0xff098200, +0x000e7080, +0x00240824, +0x10200000, +0xff050805, +0x01cf7021, +0x46220032, +0xff000000, +0x00007001, +0xff000000, +0x00017001, +0xff000000, +0xff06000b, +0x024e9021, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8ee50000, +0xff098200, +0x8d460000, +0xff098200, +0xff000000, +0x240f0000, +0xff098200, +0x118f0000, +0xff05083b, +0xff000000, +0x2d810000, +0xff098200, +0xff000000, +0x11af0000, +0xff05083b, +0xff000000, +0x00a67826, +0x01ac6826, +0x2d840000, +0xff098200, +0x0001780a, +0x000d200b, +0x01af0825, +0x0001200a, +0x10800000, +0xff05080b, +0xff000000, +0x0001700b, +0xff000000, +0x0001700a, +0xff000000, +0x8cad0000, +0xff098200, +0x11a00000, +0xff05080b, +0x00000000, +0x91ad0000, +0xff098200, +0x31ad0000, +0xff090200, +0x15a00000, +0xff05080b, +0x00000000, +0x10000000, +0xff05083a, +0x24070000, +0xff098200, +0xff000000, +0x0217b821, +0x26520004, +0x8eec0000, +0xff098200, +0x000a5042, +0x8eef0000, +0xff098200, +0x022a5023, +0x964e0000, +0xff098200, +0xff000000, +0x24010000, +0xff098200, +0x11810000, +0xff05083b, +0xff000000, +0x8d4dfffc, +0x258c0000, +0xff098200, +0x000e7080, +0x01af6826, +0x018d6025, +0x3c0f0000, +0xff090200, +0x01cf7021, +0xff000000, +0x000c700b, +0xff000000, +0x000c700a, +0xff000000, +0x024e9021, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x0217b821, +0x26520004, +0x8eec0000, +0xff098200, +0xd6e00000, +0x022a5021, +0x964e0000, +0xff098200, +0xd5420000, +0x3c0f0000, +0xff090200, +0x2d810000, +0xff098200, +0x000e7080, +0xff000000, +0x10200000, +0xff050805, +0xff000000, +0x10200000, +0xff050801, +0xff000000, +0x01cf7021, +0x46220032, +0xff000000, +0x00007001, +0x024e9021, +0xff06000b, +0xff000000, +0x00017001, +0xff06000b, +0x024e9021, +0xff000000, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0xff06000f, +0x24010000, +0xff098200, +0x11810000, +0xff05083b, +0x00000000, +0x10000000, +0xff05080b, +0x00000000, +0xff000000, +0x0217b821, +0x000a68c2, +0x8eec0000, +0xff098200, +0x964e0000, +0xff098200, +0x01a06827, +0x26520004, +0xff000000, +0x24010000, +0xff098200, +0x11810000, +0xff05083b, +0xff000000, +0x018d6026, +0x000e7080, +0x3c0f0000, +0xff090200, +0x01cf7021, +0xff000000, +0x000c700b, +0xff000000, +0x000c700a, +0xff000000, +0x024e9021, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x020a5021, +0x964e0000, +0xff098200, +0x8d4c0000, +0xff098200, +0x26520004, +0xff000000, +0x2d8c0000, +0xff098200, +0x000e7080, +0x3c0f0000, +0xff090200, +0x01cf7021, +0xff000000, +0x000c700a, +0xff000000, +0x000c700b, +0xff000000, +0x024e9021, +0xff000000, +0x2d8c0000, +0xff098200, +0xd5400000, +0xff000000, +0x11800000, +0xff050801, +0xff000000, +0x15800000, +0xff050801, +0xff000000, +0x0217b821, +0x000e7080, +0x3c0f0000, +0xff090200, +0x01cf7021, +0xf6e00000, +0x024e9021, +0xff06000b, +0xff000000, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x020a5021, +0x0217b821, +0xd5400000, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x020a5021, +0x0217b821, +0x8d4c0000, +0xff098200, +0x240d0000, +0xff098200, +0x2d8c0000, +0xff098200, +0x258d0000, +0xff098200, +0x8e4b0000, +0x26520004, +0xaeed0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x020a3021, +0x0217b821, +0x8ccc0000, +0xff098200, +0xd4c00000, +0x2d810000, +0xff098200, +0x10200000, +0xff05083c, +0x46200007, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x020a2821, +0x0217b821, +0x8cac0000, +0xff098200, +0x8ca40000, +0xff098200, +0x24010000, +0xff098200, +0x15810000, +0xff050802, +0x24010000, +0xff098200, +0x8c820000, +0xff098200, +0xff06000b, +0x44820000, +0x46800021, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000c, +0x15810000, +0xff05083e, +0x00000000, +0xff000000, +0x8c8e0000, +0xff098200, +0x15c00000, +0xff050809, +0x00000000, +0xff06000d, +0xff000000, +0xff06003f, +0x8e790000, +0xff098200, +0x0320f809, +0x00000000, +0x10000000, +0xff05080b, +0x00000000, +0xff000000, +0xff060013, +0x91cc0000, +0xff098200, +0x318c0000, +0xff090200, +0x15800000, +0xff05080d, +0x00000000, +0x10000000, +0xff05083e, +0x00000000, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0x4636a000, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0x4636a001, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0x4636a002, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0x4636a003, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0xff060098, +0x04110000, +0xff05085b, +0x4636a303, +0x46360002, +0x4620a001, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0xff000000, +0x02083021, +0x02293821, +0x8ccd0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0xff000000, +0x02083821, +0x02293021, +0x8ced0000, +0xff098200, +0xd4f60000, +0xd4d40000, +0x2da10000, +0xff098200, +0xff000000, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4d40000, +0xd4f60000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0xff000000, +0x10200000, +0xff05083d, +0x0217b821, +0x10000000, +0xff050898, +0x00000000, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0x02083021, +0x02093821, +0x8ccd0000, +0xff098200, +0x8cee0000, +0xff098200, +0xd4cc0000, +0xd4ee0000, +0x2da10000, +0xff098200, +0x2dcc0000, +0xff098200, +0x002c0824, +0x8e790000, +0xff098200, +0x10200000, +0xff05083d, +0x0217b821, +0x0320f809, +0x00000000, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0x01283023, +0xae900000, +0xff098200, +0x02092821, +0x0100a821, +0xff06002b, +0x8e790000, +0xff098200, +0x000630c2, +0xafb20014, +0x0320f809, +0x02802021, +0x14400000, +0xff050836, +0x8e900000, +0xff098200, +0x02154021, +0xd5000000, +0x0217b821, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000a6842, +0x022d6823, +0x8e4b0000, +0x26520004, +0x8dacfffc, +0x0217b821, +0x240e0000, +0xff098200, +0xaeec0000, +0xff098200, +0xaeee0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000a6842, +0x022d6823, +0x8e4b0000, +0x26520004, +0x8dacfffc, +0x0217b821, +0x240e0000, +0xff098200, +0xaeec0000, +0xff098200, +0xaeee0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000b5403, +0x448a0000, +0x0217b821, +0x46800021, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x022a5021, +0x0217b821, +0xd5400000, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000a68c2, +0x0217b821, +0x01a06027, +0x8e4b0000, +0x26520004, +0xaeec0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x0217b821, +0xaefe0000, +0xff098200, +0x26f70008, +0x020a5021, +0xff06000b, +0xaefe0000, +0xff098200, +0x02ea082a, +0x14200000, +0xff05080b, +0x26f70008, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e080000, +0xff098200, +0x000a5042, +0x01485021, +0x8d480000, +0xff098200, +0x8e4b0000, +0x26520004, +0x8d0d0000, +0xff098200, +0xd5a00000, +0x0217b821, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e080000, +0xff098200, +0x0017b842, +0x020a5021, +0x02e8b821, +0xd5400000, +0x8ee80000, +0xff098200, +0x910f0000, +0xff098200, +0x8d050000, +0xff098200, +0x31ef0000, +0xff090200, +0x910c0000, +0xff098200, +0x8d4e0000, +0xff098200, +0xf4a00000, +0x24010000, +0xff098200, +0x01ec7825, +0x11e10000, +0xff050802, +0x25ce0000, +0xff098200, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000c, +0x2dc10000, +0xff098200, +0x10200000, +0xff05080b, +0x8d4d0000, +0xff098200, +0x91af0000, +0xff098200, +0x31ef0000, +0xff090200, +0x11e00000, +0xff05080b, +0x8e790000, +0xff098200, +0x0320f809, +0x26640000, +0xff098200, +0x10000000, +0xff05080b, +0x00000000, +0xff000000, +0x8e080000, +0xff098200, +0x0017b842, +0x000a6842, +0x02e8b821, +0x022d6823, +0x8ee80000, +0xff098200, +0x8dadfffc, +0x910e0000, +0xff098200, +0x8d050000, +0xff098200, +0x91af0000, +0xff098200, +0x31c10000, +0xff090200, +0x910e0000, +0xff098200, +0x240c0000, +0xff098200, +0xacad0000, +0xff098200, +0x14200000, +0xff050802, +0xacac0000, +0xff098200, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000c, +0x11c00000, +0xff05080b, +0x31e10000, +0xff090200, +0x10200000, +0xff05080b, +0x8e790000, +0xff098200, +0x0320f809, +0x26640000, +0xff098200, +0x10000000, +0xff05080b, +0x00000000, +0xff000000, +0x8e080000, +0xff098200, +0x0017b842, +0x022a5021, +0x02e8b821, +0xd5400000, +0x8ee80000, +0xff098200, +0x8e4b0000, +0x26520004, +0x8d0d0000, +0xff098200, +0xf5a00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e080000, +0xff098200, +0x0017b842, +0x000a60c2, +0x02e8b821, +0x01806027, +0x8ee80000, +0xff098200, +0x8e4b0000, +0x26520004, +0x8d0d0000, +0xff098200, +0xadac0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e8e0000, +0xff098200, +0x000a6042, +0x3c010000, +0xff090200, +0x01816021, +0x024c9021, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0x11c00000, +0xff050801, +0x02802021, +0x0320f809, +0x02172821, +0x8e900000, +0xff098200, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x000a6842, +0x8e790000, +0xff098200, +0x022d6823, +0x8e060000, +0xff098200, +0x8da5fffc, +0xae900000, +0xff098200, +0xafb20014, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0x240c0000, +0xff098200, +0x8e4b0000, +0x26520004, +0x0217b821, +0xaeec0000, +0xff098200, +0xaee20000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e6c0000, +0xff098200, +0x8e6d0000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x018d082b, +0x10200000, +0xff050805, +0xff06000b, +0xff000000, +0x8e790000, +0xff098200, +0x000a28c2, +0x30a507ff, +0x240c0801, +0x24a1f801, +0x000a3382, +0x0181280a, +0x0320f809, +0x02802021, +0xff000000, +0x8e790000, +0xff098200, +0x000a6842, +0x022d6823, +0x02802021, +0x0320f809, +0x8da5fffc, +0xff000000, +0x8e900000, +0xff098200, +0x8e4b0000, +0x26520004, +0x0217b821, +0x240c0000, +0xff098200, +0xaee20000, +0xff098200, +0xaeec0000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8e790000, +0xff098200, +0x0140a821, +0x0320f809, +0x02802021, +0x10000000, +0xff05080b, +0x02a05021, +0xff000000, +0x8e0e0000, +0xff098200, +0x000a6842, +0x022d6823, +0x8dc80000, +0xff098200, +0x8da9fffc, +0xff000000, +0x10000000, +0xff050899, +0xff000000, +0x10000000, +0xff05089a, +0xff000000, +0x0217b821, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0x02082821, +0x02093021, +0x8cad0000, +0xff098200, +0x8cce0000, +0xff098200, +0x8ca80000, +0xff098200, +0x24010000, +0xff098200, +0xd4c00000, +0x15a10000, +0xff050830, +0x0217b821, +0x2dc10000, +0xff098200, +0x10200000, +0xff050805, +0x24010000, +0xff098200, +0x462000a4, +0x8d0c0000, +0xff098200, +0x440e1000, +0x46801121, +0x8d0d0000, +0xff098200, +0x46240032, +0x01cc082b, +0x00000801, +0x000e70c0, +0x10200000, +0xff050830, +0x01ae7021, +0x8dcc0000, +0xff098200, +0x119e0000, +0xff050802, +0xd5c00000, +0xff06000b, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000c, +0x8d0e0000, +0xff098200, +0x11c00000, +0xff05080b, +0x00000000, +0x91cc0000, +0xff098200, +0x318c0000, +0xff090200, +0x15800000, +0xff05080b, +0x00000000, +0x10000000, +0xff050830, +0x00000000, +0xff06000f, +0x15c10000, +0xff050830, +0xff000000, +0x8cc90000, +0xff098200, +0x10000000, +0xff050899, +0x00000000, +0xff000000, +0x000b4542, +0x310807f8, +0x02082821, +0x000b4b82, +0x8cac0000, +0xff098200, +0x312903fc, +0x24010000, +0xff098200, +0x8ca80000, +0xff098200, +0x02293023, +0x8cc9fffc, +0x15810000, +0xff05082d, +0x0217b821, +0xff060099, +0x8d0c0000, +0xff098200, +0x8d2d0000, +0xff098200, +0x8d0e0000, +0xff098200, +0x01ac6824, +0x000d6140, +0x000d68c0, +0x018d6823, +0x01cd7021, +0xff06000b, +0x8dc40000, +0xff098200, +0x8dcc0000, +0xff098200, +0x8dcd0000, +0xff098200, +0x8dc50000, +0xff098200, +0x24840000, +0xff098200, +0x01896026, +0x008c0825, +0x14200000, +0xff050804, +0x8d0f0000, +0xff098200, +0x10be0000, +0xff050805, +0x8dc40000, +0xff098200, +0xff06000d, +0x8e4b0000, +0x26520004, +0xaee50000, +0xff098200, +0xaee40000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000e, +0x15a00000, +0xff05080b, +0xff000000, +0x01a07021, +0xff06000f, +0x11e00000, +0xff05080d, +0x24050000, +0xff098200, +0x91ec0000, +0xff098200, +0x318c0000, +0xff090200, +0x15800000, +0xff05080d, +0x00000000, +0x10000000, +0xff05082e, +0x00000000, +0xff000000, +0x000b4542, +0x310807f8, +0x02082821, +0x314907f8, +0x8ca40000, +0xff098200, +0x24010000, +0xff098200, +0x8ca80000, +0xff098200, +0x0217b821, +0x14810000, +0xff05082f, +0x000960c2, +0x8d0d0000, +0xff098200, +0x8d0e0000, +0xff098200, +0x018d082b, +0x10200000, +0xff05082f, +0x01c94821, +0x8d2d0000, +0xff098200, +0x11be0000, +0xff050805, +0xd5200000, +0xff06000b, +0x8e4b0000, +0x26520004, +0xf6e00000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8d0e0000, +0xff098200, +0x11c00000, +0xff05080b, +0x00000000, +0x91cd0000, +0xff098200, +0x31ad0000, +0xff090200, +0x15a00000, +0xff05080b, +0x00000000, +0x10000000, +0xff05082f, +0x00000000, +0xff000000, +0x000b4542, +0x310807f8, +0x314907f8, +0x02082821, +0x02093021, +0x8cad0000, +0xff098200, +0x8cce0000, +0xff098200, +0x8ca80000, +0xff098200, +0x24010000, +0xff098200, +0xd4c00000, +0x15a10000, +0xff050834, +0x0217b821, +0x2dc10000, +0xff098200, +0x10200000, +0xff050805, +0x24010000, +0xff098200, +0x462000a4, +0x8d0c0000, +0xff098200, +0x440e1000, +0x46801121, +0x8d0d0000, +0xff098200, +0x46240032, +0x01cc082b, +0x00000801, +0x000e70c0, +0x10200000, +0xff050834, +0x01ae6821, +0x910f0000, +0xff098200, +0x8dac0000, +0xff098200, +0x119e0000, +0xff050803, +0xd6e00000, +0xff06000b, +0x31e10000, +0xff090200, +0x14200000, +0xff050807, +0xf5a00000, +0xff06000c, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000d, +0x8d0e0000, +0xff098200, +0x11c00000, +0xff05080b, +0x00000000, +0x91ce0000, +0xff098200, +0x31ce0000, +0xff090200, +0xff000000, +0x15c00000, +0xff05080b, +0x00000000, +0x10000000, +0xff050834, +0x00000000, +0xff06000f, +0x15c10000, +0xff050834, +0x8cc90000, +0xff098200, +0x10000000, +0xff05089a, +0x00000000, +0xff060011, +0x8e6c0000, +0xff098200, +0x31ef0000, +0xff090200, +0xae680000, +0xff098200, +0xa10f0000, +0xff098200, +0x10000000, +0xff05080c, +0xad0c0000, +0xff098200, +0xff000000, +0x000b4542, +0x310807f8, +0x02082821, +0x000b4b82, +0x8cac0000, +0xff098200, +0x312903fc, +0x24010000, +0xff098200, +0x02293023, +0x8ca80000, +0xff098200, +0x8cc9fffc, +0x15810000, +0xff050831, +0x0217b821, +0xff06009a, +0x8d0c0000, +0xff098200, +0x8d2d0000, +0xff098200, +0x8d0e0000, +0xff098200, +0xa1000000, +0xff098200, +0x01ac6824, +0x000d6140, +0x000d68c0, +0x018d6823, +0x01cd7021, +0xd6f40000, +0xff06000b, +0x8dc40000, +0xff098200, +0x8dcc0000, +0xff098200, +0x24010000, +0xff098200, +0x8dcd0000, +0xff098200, +0x14810000, +0xff050805, +0x8dc50000, +0xff098200, +0x15890000, +0xff050805, +0x910f0000, +0xff098200, +0x10be0000, +0xff050804, +0x8d0c0000, +0xff098200, +0xff06000c, +0x31e10000, +0xff090200, +0x14200000, +0xff050807, +0xff000000, +0xf5d40000, +0xff098200, +0xff06000d, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000e, +0x11800000, +0xff05080c, +0x00000000, +0x918c0000, +0xff098200, +0x318c0000, +0xff090200, +0x15800000, +0xff05080c, +0x00000000, +0x10000000, +0xff050832, +0x00000000, +0xff06000f, +0x15a00000, +0xff05080b, +0x01a07021, +0x8d0e0000, +0xff098200, +0x11c00000, +0xff050806, +0x26660000, +0xff098200, +0x91cc0000, +0xff098200, +0x318c0000, +0xff090200, +0x11800000, +0xff050832, +0x24010000, +0xff098200, +0xff060010, +0x8e790000, +0xff098200, +0xacc90000, +0xff098200, +0xacc10000, +0xff098200, +0xae900000, +0xff098200, +0x01002821, +0xafb20014, +0x0320f809, +0x02802021, +0x8e900000, +0xff098200, +0xff000000, +0x10000000, +0xff05080d, +0xf4540000, +0xff060011, +0x8e6c0000, +0xff098200, +0x31ef0000, +0xff090200, +0xae680000, +0xff098200, +0xa10f0000, +0xff098200, +0x10000000, +0xff05080d, +0xad0c0000, +0xff098200, +0xff000000, +0x000b4542, +0x310807f8, +0x02082821, +0x314907f8, +0x8ca40000, +0xff098200, +0x24010000, +0xff098200, +0x8ca80000, +0xff098200, +0x0217b821, +0x14810000, +0xff050833, +0x000960c2, +0x8d0d0000, +0xff098200, +0x8d0e0000, +0xff098200, +0x018d082b, +0x10200000, +0xff050833, +0x01c94821, +0x8d2d0000, +0xff098200, +0x910f0000, +0xff098200, +0x11be0000, +0xff050805, +0xd6e00000, +0xff06000b, +0x31e10000, +0xff090200, +0x14200000, +0xff050807, +0xf5200000, +0xff06000c, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8d0e0000, +0xff098200, +0x11c00000, +0xff05080b, +0x00000000, +0x91cd0000, +0xff098200, +0x31ad0000, +0xff090200, +0x15a00000, +0xff05080b, +0x00000000, +0x10000000, +0xff050833, +0x00000000, +0xff060011, +0x8e6c0000, +0xff098200, +0xff000000, +0x31ef0000, +0xff090200, +0xae680000, +0xff098200, +0xa10f0000, +0xff098200, +0x10000000, +0xff05080c, +0xad0c0000, +0xff098200, +0xff000000, +0x0217b821, +0xff06000b, +0x022a7821, +0x8ee50000, +0xff098200, +0x26acfff8, +0x8def0000, +0xff098200, +0x11800000, +0xff050804, +0x000c30c2, +0x00cf3021, +0x8cae0000, +0xff098200, +0x000f68c0, +0x90af0000, +0xff098200, +0x8ca40000, +0xff098200, +0x01c6082b, +0x14200000, +0xff050805, +0x02ec7021, +0x01a46821, +0x31ec0000, +0xff090200, +0xff06000d, +0xd6e00000, +0x26f70008, +0x02ee082b, +0xf5a00000, +0x14200000, +0xff05080d, +0x25ad0008, +0x15800000, +0xff050807, +0x00000000, +0xff06000e, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8e790000, +0xff098200, +0xae900000, +0xff098200, +0xafb20014, +0x01408021, +0x0320f809, +0x02802021, +0x02005021, +0x10000000, +0xff05080b, +0x8e900000, +0xff098200, +0xff060011, +0x8e6c0000, +0xff098200, +0x31ef0000, +0xff090200, +0xae650000, +0xff098200, +0xa0af0000, +0xff098200, +0xff000000, +0x10000000, +0xff05080e, +0xacac0000, +0xff098200, +0xff000000, +0x314907f8, +0x10000000, +0xff05089b, +0x01354821, +0xff000000, +0x314907f8, +0xff06009b, +0x02007021, +0x02178021, +0x24010000, +0xff098200, +0x8e0c0000, +0xff098200, +0x8e080000, +0xff098200, +0x26100008, +0x15810000, +0xff050825, +0x2529fff8, +0xae120000, +0xff098200, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff000000, +0x01555021, +0xff000000, +0x0217b821, +0x24010000, +0xff098200, +0x8eec0000, +0xff098200, +0x8ee80000, +0xff098200, +0x01404821, +0x8e0d0000, +0xff098200, +0x26f70008, +0x15810000, +0xff050840, +0x2529fff8, +0xff060041, +0x31ac0000, +0xff090200, +0x910f0000, +0xff098200, +0x15800000, +0xff050807, +0x39ae0000, +0xff090200, +0xff06000b, +0xae080000, +0xff098200, +0x2de10002, +0x02007021, +0x11200000, +0xff050803, +0x01207821, +0xff06000c, +0xd6e00000, +0x26f70008, +0x25effff8, +0xf5c00000, +0x15e00000, +0xff05080c, +0x25ce0008, +0xff06000d, +0x01816025, +0x11800000, +0xff050805, +0x00000000, +0xff06000e, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff06000f, +0x8dabfffc, +0x000bb942, +0x32f707f8, +0x02176823, +0x8dad0000, +0xff098200, +0x8dad0000, +0xff098200, +0x10000000, +0xff05080e, +0xff000000, +0x8db10000, +0xff098200, +0xff060011, +0x31c10000, +0xff090200, +0x14200000, +0xff05080b, +0x020e7023, +0x01c08021, +0x8dcd0000, +0xff098200, +0x10000000, +0xff05080b, +0x31ac0000, +0xff090200, +0xff000000, +0x02007021, +0x02178021, +0x24010000, +0xff098200, +0x8e0d0000, +0xff098200, +0x8e080000, +0xff098200, +0xd602fff8, +0xd600fff0, +0xae0d0000, +0xff098200, +0xae080000, +0xff098200, +0xf6020010, +0xf6000008, +0x26100008, +0x15a10000, +0xff050825, +0x24090010, +0xae120000, +0xff098200, +0x8d120000, +0xff098200, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000bb942, +0x000d6880, +0x32f707f8, +0x026d6021, +0x8d8c0000, +0x01800008, +0x02f0b821, +0xff000000, +0x0217b821, +0x8ee80000, +0xff098200, +0x8ee90000, +0xff098200, +0x8d0c0000, +0xff098200, +0x8d0d0000, +0xff098200, +0x26520004, +0xff06000b, +0x012c082b, +0x10200000, +0xff050805, +0x000978c0, +0x01af7821, +0x8dee0000, +0xff098200, +0xd5e00000, +0x44891000, +0x964a0000, +0xff098200, +0x11de0000, +0xff05080b, +0x25290001, +0x468010a1, +0x3c0f0000, +0xff090200, +0xf6e00008, +0x000a5080, +0x014f5021, +0xaee90000, +0xff098200, +0x024a9021, +0xf6e20000, +0xff06000d, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8d0d0000, +0xff098200, +0x012c4823, +0x8d0e0000, +0xff098200, +0xff060010, +0x01a9082b, +0x14200000, +0xff05080d, +0x00097940, +0x000940c0, +0x01e87823, +0x01ee7821, +0x8de80000, +0xff098200, +0xd5e00000, +0x964a0000, +0xff098200, +0x111e0000, +0xff050810, +0x25290001, +0xd5e20000, +0xff098200, +0x3c0f0000, +0xff090200, +0xf6e00008, +0x012c4821, +0x000a5080, +0x014f5021, +0xf6e20000, +0x024a9021, +0x10000000, +0xff05080d, +0xff000000, +0xaee90000, +0xff098200, +0xff000000, +0x0217b821, +0x8eec0000, +0xff098200, +0x8eed0000, +0xff098200, +0x8eee0000, +0xff098200, +0x8eef0000, +0xff098200, +0x24010000, +0xff098200, +0x15810000, +0xff050805, +0x25ce0000, +0xff098200, +0x91ad0000, +0xff098200, +0x25ef0000, +0xff098200, +0x000a6042, +0x01cf7025, +0x25ad0000, +0xff098200, +0x024c6021, +0x01ae6825, +0x15a00000, +0xff050805, +0x3c0e0000, +0xff090200, +0x018e9021, +0xaee00000, +0xff098200, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x240f0000, +0xff098200, +0x240d0000, +0xff098200, +0xa24f0000, +0xff098200, +0x018e9021, +0x10000000, +0xff05080b, +0xa24d0000, +0xff098200, +0xff000000, +0x8e0c0000, +0xff098200, +0x314907f8, +0x000b4542, +0x02094821, +0x310807f8, +0x0217b821, +0x25290000, +0xff098200, +0x02e87021, +0x260ffff8, +0x012c4823, +0x11000000, +0xff050805, +0x01e96823, +0x25cefff0, +0xff06000b, +0x8d240000, +0xff098200, +0x012f082b, +0x8d250000, +0xff098200, +0x25290008, +0x03c1200a, +0xaee40000, +0xff098200, +0xaee50000, +0xff098200, +0x02ee082b, +0x14200000, +0xff05080b, +0x26f70008, +0xff06000d, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff06000f, +0x8e8c0000, +0xff098200, +0x19a00000, +0xff05080d, +0x24150008, +0x02ed7021, +0x018e082b, +0x14200000, +0xff050807, +0x25b50008, +0xff060010, +0xd5200000, +0x25290008, +0xf6e00000, +0x012f082b, +0x14200000, +0xff050810, +0x26f70008, +0x10000000, +0xff05080d, +0x00000000, +0xff060011, +0x8e790000, +0xff098200, +0xae970000, +0xff098200, +0x02f0b823, +0xae900000, +0xff098200, +0x01308023, +0xafb20014, +0x000d28c2, +0x0320f809, +0x02802021, +0x02004821, +0x8e900000, +0xff098200, +0x0217b821, +0x02094821, +0x10000000, +0xff050810, +0xff000000, +0x260ffff8, +0xff000000, +0x01555021, +0xff000000, +0x8e120000, +0xff098200, +0x0217b821, +0x0140a821, +0xff06000b, +0x324c0000, +0xff090200, +0x15800000, +0xff05089c, +0x3a4d0000, +0xff090200, +0xff060017, +0x8e4bfffc, +0x260efff8, +0x2549fff8, +0x000b6142, +0x000b4542, +0x318c07f8, +0x310807f8, +0x01c87821, +0x11200000, +0xff050803, +0x01cc8023, +0xff06000c, +0xd6e00000, +0x26f70008, +0x2529fff8, +0xf5c00000, +0x15200000, +0xff05080c, +0x25ce0008, +0xff06000d, +0x25effff8, +0xff06000f, +0x01cf082b, +0x14200000, +0xff050806, +0x8e0d0000, +0xff098200, +0x8e4b0000, +0x26520004, +0x8dad0000, +0xff098200, +0x8db10000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff060010, +0xadde0000, +0xff098200, +0x10000000, +0xff05080f, +0x25ce0008, +0xff06009c, +0x31ae0000, +0xff090200, +0x15c00000, +0xff050818, +0x00000000, +0x020d8023, +0x10000000, +0xff05080b, +0x8e120000, +0xff098200, +0xff000000, +0x8e120000, +0xff098200, +0x0217b821, +0x0140a821, +0x324c0000, +0xff090200, +0x15800000, +0xff05089c, +0x3a4d0000, +0xff090200, +0x8e4bfffc, +0x260efff8, +0xff000000, +0xd6e00000, +0xff000000, +0x000b4542, +0x000bb942, +0x310807f8, +0x32f707f8, +0xff000000, +0xf5c00000, +0xff000000, +0x01d78023, +0xff06000f, +0x0148082b, +0x14200000, +0xff050806, +0x8e0d0000, +0xff098200, +0x8e4b0000, +0x26520004, +0x8dad0000, +0xff098200, +0x8db10000, +0xff098200, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff060010, +0x25ce0008, +0x254a0008, +0x10000000, +0xff05080f, +0xff000000, +0xadde0000, +0xff098200, +0xff000000, +0xadde0000, +0xff098200, +0xff000000, +0xf0f0f0f0, +0xff000000, +0x0217b821, +0xff000000, +0xd6e00000, +0xff098200, +0xd6e40000, +0xff098200, +0xd6e20000, +0xff098200, +0x8eef0000, +0xff098200, +0x46240000, +0xf6e00000, +0xff098200, +0xff000000, +0x8eed0000, +0xff098200, +0x8eef0000, +0xff098200, +0x8eee0000, +0xff098200, +0x2dad0000, +0xff098200, +0x2dec0000, +0xff098200, +0x2dce0000, +0xff098200, +0x01ac6824, +0x01ae6824, +0xd6e00000, +0xff098200, +0x11a00000, +0xff050842, +0xd6e20000, +0xff098200, +0xff000000, +0x000a5042, +0x3c0c0000, +0xff090200, +0xff000000, +0x4622003e, +0x4620113e, +0xf6e00000, +0xff098200, +0xff000000, +0x240d0001, +0x240e0001, +0x8e4bfffc, +0x01e0782a, +0x00016801, +0x00057001, +0x014c9021, +0x01cf680b, +0x000b5402, +0x15a00000, +0xff070800, +0x000a50c0, +0xff000000, +0x240d0001, +0x240e0001, +0x01e0782a, +0x00006801, +0x00047001, +0x01cf680b, +0x15a00000, +0xff070800, +0x00000000, +0xff000000, +0x014c6821, +0x01e0782a, +0x01a07021, +0xff000000, +0x00016801, +0x00057001, +0xff000000, +0x00006801, +0x00047001, +0xff000000, +0x01cf680b, +0x024d9021, +0xff000000, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0xf0f0f0f0, +0xff000000, +0x0217b821, +0x8eed0000, +0xff098200, +0x11be0000, +0xff050801, +0x8eee0000, +0xff098200, +0xff000000, +0xaeed0000, +0xff098200, +0x10000000, +0xff070800, +0xaeee0000, +0xff098200, +0xff000000, +0x000a6042, +0x3c010000, +0xff090200, +0x01816021, +0x024c9021, +0xaeed0000, +0xff098200, +0xaeee0000, +0xff098200, +0xff000000, +0xff06000b, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0xf0f0f0f0, +0xff000000, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8e6d0000, +0xff098200, +0x000a5042, +0x24010000, +0x01aa6821, +0xae610000, +0xff098200, +0x8dae0000, +0xae700000, +0xff098200, +0xae740000, +0xff098200, +0x8dce0000, +0xff098200, +0x01c00008, +0x267e0000, +0xff098200, +0xff000000, +0x000a6042, +0x3c010000, +0xff090200, +0x01816021, +0x024c9021, +0x8e4b0000, +0x26520004, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0xf0f0f0f0, +0xff000000, +0x8e8e0000, +0xff098200, +0x924d0000, +0xff098200, +0x8e510000, +0xff098200, +0x01d7082b, +0x14200000, +0xff050820, +0x000d68c0, +0xff000000, +0x8e4b0000, +0x26520004, +0xff000000, +0xff06000c, +0x012d082b, +0x14200000, +0xff050803, +0x02090821, +0xff000000, +0x000b5402, +0x10000000, +0xff070800, +0x000a50c0, +0xff000000, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0xff06000d, +0xac3e0000, +0xff098200, +0x10000000, +0xff05080c, +0x25290008, +0xff000000, +0xf0f0f0f0, +0xff000000, +0x02096821, +0x8e8e0000, +0xff098200, +0x02e96021, +0xada80000, +0xff098200, +0x252f0000, +0xff098200, +0x018e082b, +0x8e510000, +0xff098200, +0x10200000, +0xff050820, +0xadaf0000, +0xff098200, +0x924e0000, +0xff098200, +0x0200b821, +0x01a04821, +0x8e4b0000, +0x26520004, +0x11c00000, +0xff050803, +0x25b00008, +0xff06000b, +0x8eec0000, +0xff098200, +0x8eef0000, +0xff098200, +0x02e9082b, +0x01802021, +0x03c1600a, +0x03c1200b, +0xadaf0000, +0xff098200, +0x25ceffff, +0xadac0000, +0xff098200, +0x25ad0008, +0xaee40000, +0xff098200, +0x15c00000, +0xff05080b, +0x26f70008, +0xff06000d, +0x316d00ff, +0x000d6880, +0x026d6021, +0x000b5402, +0x8d810000, +0x000bb942, +0x000a50c0, +0x00200008, +0x32f707f8, +0xff000000, +0x8d190000, +0xff098200, +0xff000000, +0x8e790000, +0xff098200, +0xff000000, +0x02e96821, +0x8e8e0000, +0xff098200, +0x02094821, +0xae900000, +0xff098200, +0x01cd082b, +0xae890000, +0xff098200, +0x240c0000, +0xff098200, +0xff000000, +0x8d050000, +0xff098200, +0xff000000, +0x14200000, +0xff05081f, +0x02802021, +0x0320f809, +0xae6c0000, +0xff098200, +0x8e900000, +0xff098200, +0x000250c0, +0x8e8d0000, +0xff098200, +0x240c0000, +0xff098200, +0x8e120000, +0xff098200, +0x01aab823, +0x10000000, +0xff050816, +0xae6c0000, +0xff098200, +0xff000000, +0xff010000 +}; + +enum { + GLOB_vm_returnp, + GLOB_cont_dispatch, + GLOB_vm_returnc, + GLOB_BC_RET_Z, + GLOB_vm_return, + GLOB_vm_leave_cp, + GLOB_vm_leave_unw, + GLOB_vm_unwind_c, + GLOB_vm_unwind_c_eh, + GLOB_vm_unwind_ff, + GLOB_vm_unwind_ff_eh, + GLOB_vm_growstack_c, + GLOB_vm_growstack_l, + GLOB_vm_resume, + GLOB_vm_pcall, + GLOB_vm_call, + GLOB_vm_call_dispatch, + GLOB_vmeta_call, + GLOB_vm_call_dispatch_f, + GLOB_vm_cpcall, + GLOB_cont_ffi_callback, + GLOB_vm_call_tail, + GLOB_cont_cat, + GLOB_BC_CAT_Z, + GLOB_cont_nop, + GLOB_vmeta_tgets1, + GLOB_vmeta_tgets, + GLOB_vmeta_tgetb, + GLOB_vmeta_tgetv, + GLOB_vmeta_tsets1, + GLOB_vmeta_tsets, + GLOB_vmeta_tsetb, + GLOB_vmeta_tsetv, + GLOB_vmeta_comp, + GLOB_vmeta_binop, + GLOB_cont_ra, + GLOB_cont_condt, + GLOB_cont_condf, + GLOB_vmeta_equal, + GLOB_vmeta_equal_cd, + GLOB_vmeta_unm, + GLOB_vmeta_arith, + GLOB_vmeta_len, + GLOB_BC_LEN_Z, + GLOB_vmeta_callt, + GLOB_BC_CALLT_Z, + GLOB_vmeta_for, + GLOB_ff_assert, + GLOB_fff_fallback, + GLOB_fff_res, + GLOB_ff_type, + GLOB_fff_resn, + GLOB_ff_getmetatable, + GLOB_fff_restv, + GLOB_ff_setmetatable, + GLOB_ff_rawget, + GLOB_ff_tonumber, + GLOB_ff_tostring, + GLOB_fff_gcstep, + GLOB_ff_next, + GLOB_ff_pairs, + GLOB_ff_ipairs_aux, + GLOB_ff_ipairs, + GLOB_ff_pcall, + GLOB_ff_xpcall, + GLOB_ff_coroutine_resume, + GLOB_ff_coroutine_wrap_aux, + GLOB_ff_coroutine_yield, + GLOB_ff_math_abs, + GLOB_fff_res1, + GLOB_ff_math_floor, + GLOB_vm_floor, + GLOB_ff_math_ceil, + GLOB_vm_ceil, + GLOB_ff_math_log, + GLOB_ff_math_log10, + GLOB_ff_math_exp, + GLOB_ff_math_sin, + GLOB_ff_math_cos, + GLOB_ff_math_tan, + GLOB_ff_math_asin, + GLOB_ff_math_acos, + GLOB_ff_math_atan, + GLOB_ff_math_sinh, + GLOB_ff_math_cosh, + GLOB_ff_math_tanh, + GLOB_ff_math_pow, + GLOB_ff_math_atan2, + GLOB_ff_math_fmod, + GLOB_ff_math_sqrt, + GLOB_ff_math_deg, + GLOB_ff_math_rad, + GLOB_ff_math_ldexp, + GLOB_ff_math_frexp, + GLOB_ff_math_modf, + GLOB_ff_math_min, + GLOB_ff_math_max, + GLOB_ff_string_len, + GLOB_fff_resi, + GLOB_ff_string_byte, + GLOB_ff_string_char, + GLOB_fff_newstr, + GLOB_ff_string_sub, + GLOB_fff_emptystr, + GLOB_ff_string_rep, + GLOB_ff_string_reverse, + GLOB_ff_string_lower, + GLOB_ff_string_upper, + GLOB_ff_table_getn, + GLOB_ff_bit_band, + GLOB_ff_bit_bor, + GLOB_ff_bit_bxor, + GLOB_ff_bit_bswap, + GLOB_ff_bit_bnot, + GLOB_ff_bit_lshift, + GLOB_ff_bit_rshift, + GLOB_ff_bit_arshift, + GLOB_ff_bit_rol, + GLOB_ff_bit_ror, + GLOB_ff_bit_tobit, + GLOB_vm_record, + GLOB_vm_rethook, + GLOB_vm_inshook, + GLOB_cont_hook, + GLOB_vm_hotloop, + GLOB_vm_callhook, + GLOB_vm_hotcall, + GLOB_vm_exit_handler, + GLOB_vm_exit_interp, + GLOB_vm_trunc, + GLOB_vm_ffi_callback, + GLOB_vm_ffi_call, + GLOB_BC_MODVN_Z, + GLOB_BC_TGETS_Z, + GLOB_BC_TSETS_Z, + GLOB_BC_CALL_Z, + GLOB_BC_RETV_Z, + GLOB__MAX +}; +static const char *const globnames[] = { + "vm_returnp", + "cont_dispatch", + "vm_returnc", + "BC_RET_Z", + "vm_return", + "vm_leave_cp", + "vm_leave_unw", + "vm_unwind_c", + "vm_unwind_c_eh", + "vm_unwind_ff", + "vm_unwind_ff_eh", + "vm_growstack_c", + "vm_growstack_l", + "vm_resume", + "vm_pcall", + "vm_call", + "vm_call_dispatch", + "vmeta_call", + "vm_call_dispatch_f", + "vm_cpcall", + "cont_ffi_callback", + "vm_call_tail", + "cont_cat", + "BC_CAT_Z", + "cont_nop", + "vmeta_tgets1", + "vmeta_tgets", + "vmeta_tgetb", + "vmeta_tgetv", + "vmeta_tsets1", + "vmeta_tsets", + "vmeta_tsetb", + "vmeta_tsetv", + "vmeta_comp", + "vmeta_binop", + "cont_ra", + "cont_condt", + "cont_condf", + "vmeta_equal", + "vmeta_equal_cd", + "vmeta_unm", + "vmeta_arith", + "vmeta_len", + "BC_LEN_Z", + "vmeta_callt", + "BC_CALLT_Z", + "vmeta_for", + "ff_assert", + "fff_fallback", + "fff_res", + "ff_type", + "fff_resn", + "ff_getmetatable", + "fff_restv", + "ff_setmetatable", + "ff_rawget", + "ff_tonumber", + "ff_tostring", + "fff_gcstep", + "ff_next", + "ff_pairs", + "ff_ipairs_aux", + "ff_ipairs", + "ff_pcall", + "ff_xpcall", + "ff_coroutine_resume", + "ff_coroutine_wrap_aux", + "ff_coroutine_yield", + "ff_math_abs", + "fff_res1", + "ff_math_floor", + "vm_floor", + "ff_math_ceil", + "vm_ceil", + "ff_math_log", + "ff_math_log10", + "ff_math_exp", + "ff_math_sin", + "ff_math_cos", + "ff_math_tan", + "ff_math_asin", + "ff_math_acos", + "ff_math_atan", + "ff_math_sinh", + "ff_math_cosh", + "ff_math_tanh", + "ff_math_pow", + "ff_math_atan2", + "ff_math_fmod", + "ff_math_sqrt", + "ff_math_deg", + "ff_math_rad", + "ff_math_ldexp", + "ff_math_frexp", + "ff_math_modf", + "ff_math_min", + "ff_math_max", + "ff_string_len", + "fff_resi", + "ff_string_byte", + "ff_string_char", + "fff_newstr", + "ff_string_sub", + "fff_emptystr", + "ff_string_rep", + "ff_string_reverse", + "ff_string_lower", + "ff_string_upper", + "ff_table_getn", + "ff_bit_band", + "ff_bit_bor", + "ff_bit_bxor", + "ff_bit_bswap", + "ff_bit_bnot", + "ff_bit_lshift", + "ff_bit_rshift", + "ff_bit_arshift", + "ff_bit_rol", + "ff_bit_ror", + "ff_bit_tobit", + "vm_record", + "vm_rethook", + "vm_inshook", + "cont_hook", + "vm_hotloop", + "vm_callhook", + "vm_hotcall", + "vm_exit_handler", + "vm_exit_interp", + "vm_trunc", + "vm_ffi_callback", + "vm_ffi_call", + "BC_MODVN_Z", + "BC_TGETS_Z", + "BC_TSETS_Z", + "BC_CALL_Z", + "BC_RETV_Z", + (const char *)0 +}; +static const char *const extnames[] = { + (const char *)0 +}; +#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V) +#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V) +#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V) +#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V) +#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V) +#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V) +#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V) +#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V) +#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V) +#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V) +#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V) +#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V) +#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V) +#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field)) +#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field)) +#define GG_DISP2GOT (GG_OFS(got) - GG_OFS(dispatch)) +#define DISPATCH_GOT(name) (GG_DISP2GOT + 4*LJ_GOT_##name) +#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto)) + +/* Generate subroutines used by opcodes and other parts of the VM. */ +/* The .code_sub section should be last to help static branch prediction. */ +static void build_subroutines(BuildCtx *ctx) +{ + dasm_put(Dst, 0); + dasm_put(Dst, 1, FRAME_P, LJ_TTRUE, LJ_ENDIAN_SELECT(-4,-8), LJ_ENDIAN_SELECT(-4,-8), FRAME_TYPE, FRAME_C, Dt1(->base), ~LJ_VMST_C, DISPATCH_GL(vmstate), Dt1(->top)); + dasm_put(Dst, 57, Dt1(->cframe), 72+9*4, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4, 24+3*8, 72+3*4, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, Dt1(->maxstack), LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 109, DISPATCH_GOT(lj_state_growstack), Dt1(->top), ~LJ_VMST_C, Dt1(->glref), Dt2(->vmstate), LJ_TNIL, Dt1(->base), Dt1(->glref), LJ_TFALSE, ~LJ_VMST_INTERP, LJ_ENDIAN_SELECT(-4,-8), GG_G2DISP, LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 172, DISPATCH_GL(vmstate), LUA_MINSTACK, Dt1(->base), Dt1(->top), DISPATCH_GOT(lj_state_growstack), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc), 72+9*4, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4); + dasm_put(Dst, 235, 24+3*8, 72+3*4, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, Dt1(->glref), Dt1(->status), FRAME_CP, CFRAME_RESUME, GG_G2DISP, Dt1(->cframe), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-4,-8), Dt1(->status), ~LJ_VMST_INTERP, DISPATCH_GL(vmstate), FRAME_TYPE); + dasm_put(Dst, 296, LJ_TNIL, 72+9*4, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4, 24+3*8, 72+3*4, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, FRAME_CP, 72+9*4); + dasm_put(Dst, 345, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4, 24+3*8, 72+3*4, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, FRAME_C, Dt1(->cframe), Dt1(->cframe), Dt1(->glref), GG_G2DISP, Dt1(->base)); + dasm_put(Dst, 396, Dt1(->top), ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate), LJ_ENDIAN_SELECT(-4,-8), LJ_TFUNC, LJ_ENDIAN_SELECT(-8,-4), LJ_ENDIAN_SELECT(-4,-8), Dt7(->pc), 72+9*4, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4, 24+3*8, 72+3*4); + dasm_put(Dst, 457, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe), Dt1(->glref), FRAME_CP, GG_G2DISP, -16+LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(-8,-4)); +#if LJ_HASFFI + dasm_put(Dst, 506); +#endif + dasm_put(Dst, 508, -16+LJ_ENDIAN_SELECT(4,0), Dt7(->pc)); +#if LJ_HASFFI + dasm_put(Dst, 514); +#endif + dasm_put(Dst, 517, -8+LJ_ENDIAN_SELECT(4,0), PC2PROTO(k)); +#if LJ_HASFFI + dasm_put(Dst, 523); +#endif + dasm_put(Dst, 531, Dt1(->base), DISPATCH_GL(tmptv), LJ_TSTR, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), DISPATCH_GL(tmptv), LJ_TTAB, LJ_ENDIAN_SELECT(0,4), DISPATCH_GL(tmptv2), LJ_ENDIAN_SELECT(4,0), LJ_TSTR, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), DISPATCH_GL(tmptv)); + dasm_put(Dst, 589, DISPATCH_GOT(lj_meta_tget), Dt1(->base), -FRAME_CONT, Dt1(->top), -16+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(-8,-4), DISPATCH_GL(tmptv), LJ_TSTR, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), DISPATCH_GL(tmptv), LJ_TTAB, LJ_ENDIAN_SELECT(0,4), DISPATCH_GL(tmptv2), LJ_ENDIAN_SELECT(4,0), LJ_TSTR, LJ_ENDIAN_SELECT(0,4)); + dasm_put(Dst, 651, LJ_ENDIAN_SELECT(4,0), DISPATCH_GL(tmptv), DISPATCH_GOT(lj_meta_tset), Dt1(->base), -FRAME_CONT, Dt1(->top), -16+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(-8,-4), DISPATCH_GOT(lj_meta_comp), Dt1(->base), LJ_ENDIAN_SELECT(2,0), (-(BCBIAS_J*4 >> 16) & 65535)); + dasm_put(Dst, 721, -4+LJ_ENDIAN_SELECT(1,2), LJ_ENDIAN_SELECT(4,0), LJ_TISTRUECOND, LJ_ENDIAN_SELECT(4,0), LJ_TISTRUECOND, DISPATCH_GOT(lj_meta_equal), Dt1(->base)); +#if LJ_HASFFI + dasm_put(Dst, 776, DISPATCH_GOT(lj_meta_equal_cd), Dt1(->base)); +#endif + dasm_put(Dst, 789, DISPATCH_GOT(lj_meta_arith), Dt1(->base), -16+LJ_ENDIAN_SELECT(4,0), FRAME_CONT); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 818); +#endif + dasm_put(Dst, 820, DISPATCH_GOT(lj_meta_len), Dt1(->base)); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 828); +#else + dasm_put(Dst, 835); +#endif + dasm_put(Dst, 839, DISPATCH_GOT(lj_meta_call), Dt1(->base), LJ_ENDIAN_SELECT(-8,-4), LJ_ENDIAN_SELECT(-4,-8), Dt7(->pc), DISPATCH_GOT(lj_meta_call), Dt1(->base), LJ_ENDIAN_SELECT(-4,-8), LJ_ENDIAN_SELECT(-8,-4), DISPATCH_GOT(lj_meta_for), Dt1(->base)); +#if LJ_HASJIT + dasm_put(Dst, 896, BC_JFORI); +#endif + dasm_put(Dst, 900); +#if LJ_HASJIT + dasm_put(Dst, 904, BC_JFORI, BC_FORI); +#else + dasm_put(Dst, 911, BC_FORI); +#endif + dasm_put(Dst, 915, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TISTRUECOND, LJ_ENDIAN_SELECT(-4,-8), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, Dt8(->upvalue), LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 970, LJ_ENDIAN_SELECT(0,4), LJ_TTAB, LJ_TUDATA, Dt6(->metatable), DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable]), LJ_TNIL, Dt6(->hmask), LJ_TTAB, Dt5(->hash), Dt6(->node), LJ_TSTR, offsetof(Node, key)+LJ_ENDIAN_SELECT(4,0), offsetof(Node, key)+LJ_ENDIAN_SELECT(0,4), DtB(->next), offsetof(Node, val)+LJ_ENDIAN_SELECT(4,0), offsetof(Node, val)+LJ_ENDIAN_SELECT(0,4)); + dasm_put(Dst, 1020, LJ_TISNUM, LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT]), LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), 8+LJ_ENDIAN_SELECT(0,4), LJ_TTAB, -LJ_TTAB, Dt6(->metatable), Dt6(->marked)); + dasm_put(Dst, 1075, LJ_GC_BLACK, Dt6(->metatable), DISPATCH_GL(gc.grayagain), ~LJ_GC_BLACK & 255, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), DISPATCH_GOT(lj_tab_get), -LJ_TTAB, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM); + dasm_put(Dst, 1129, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]), LJ_TISNUM, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), DISPATCH_GOT(lj_str_fromnum), LJ_TSTR, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TTAB, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(-4,-8), DISPATCH_GOT(lj_tab_next)); + dasm_put(Dst, 1184, Dt1(->base), Dt1(->top), LJ_TNIL, (2+1)*8, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TTAB, LJ_ENDIAN_SELECT(-4,-8)); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 1219, Dt6(->metatable), Dt8(->upvalue[0])); +#else + dasm_put(Dst, 1226, Dt8(->upvalue[0])); +#endif + dasm_put(Dst, 1229, 8+LJ_ENDIAN_SELECT(4,0), (3+1)*8, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), 8+LJ_ENDIAN_SELECT(4,0), -LJ_TTAB, LJ_TISNUM, LJ_ENDIAN_SELECT(-4,-8), Dt6(->asize), Dt6(->array), LJ_ENDIAN_SELECT(4,0), (0+1)*8, (2+1)*8, Dt6(->hmask)); + dasm_put(Dst, 1292, DISPATCH_GOT(lj_tab_getinth), (0+1)*8, (0+1)*8, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TTAB, LJ_ENDIAN_SELECT(-4,-8)); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 1323, Dt6(->metatable), Dt8(->upvalue[0])); +#else + dasm_put(Dst, 1330, Dt8(->upvalue[0])); +#endif + dasm_put(Dst, 1333, 8+LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(0,4), (3+1)*8, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 8+FRAME_PCALL, 8+LJ_ENDIAN_SELECT(4,0), DISPATCH_GL(hookmask), LJ_TFUNC, HOOK_ACTIVE_SHIFT, 16+FRAME_PCALL, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4)); + dasm_put(Dst, 1392, LJ_TTHREAD, Dt1(->status), Dt1(->cframe), Dt1(->top), Dt1(->base), -LUA_YIELD, Dt1(->maxstack), LJ_ENDIAN_SELECT(-4,-8), Dt1(->base), Dt1(->top), Dt1(->top)); + dasm_put(Dst, 1451, Dt1(->base), LUA_YIELD+1, Dt1(->top), ~LJ_VMST_INTERP, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->maxstack), Dt1(->top), FRAME_TYPE, LJ_TTRUE, -8+LJ_ENDIAN_SELECT(4,0), LJ_TFALSE, Dt1(->top)); + dasm_put(Dst, 1511, (2+1)*8, -8+LJ_ENDIAN_SELECT(4,0), FRAME_TYPE, DISPATCH_GOT(lj_state_growstack), Dt8(->upvalue[0].gcr), Dt1(->status), Dt1(->cframe), Dt1(->top), Dt1(->base), -LUA_YIELD, Dt1(->maxstack), LJ_ENDIAN_SELECT(-4,-8), Dt1(->base), Dt1(->top)); + dasm_put(Dst, 1566, Dt1(->top), Dt1(->base), LUA_YIELD+1, Dt1(->top), ~LJ_VMST_INTERP, Dt1(->base), DISPATCH_GL(vmstate), Dt1(->maxstack), Dt1(->top), FRAME_TYPE); + dasm_put(Dst, 1627, DISPATCH_GOT(lj_ffh_coroutine_wrap_err), DISPATCH_GOT(lj_state_growstack), Dt1(->cframe), Dt1(->base), CFRAME_RESUME, Dt1(->top), LUA_YIELD, Dt1(->cframe), Dt1(->status), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM); + dasm_put(Dst, 1682, LJ_ENDIAN_SELECT(-4,-8), LJ_ENDIAN_SELECT(-4,-8), -8+LJ_ENDIAN_SELECT(4,0), -8+LJ_ENDIAN_SELECT(0,4), (1+1)*8, FRAME_TYPE, -8+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM); + dasm_put(Dst, 1750, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(log), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(log10), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 1806, DISPATCH_GOT(exp), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(sin), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(cos), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(tan)); + dasm_put(Dst, 1862, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(asin), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(acos), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(atan), LJ_TISNUM); + dasm_put(Dst, 1918, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(sinh), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(cosh), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(tanh), LJ_TISNUM); + dasm_put(Dst, 1977, LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, DISPATCH_GOT(pow), LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, DISPATCH_GOT(atan2), LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM); + dasm_put(Dst, 2039, DISPATCH_GOT(fmod), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, Dt8(->upvalue[0]), LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM); + dasm_put(Dst, 2094, DISPATCH_GOT(ldexp), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, DISPATCH_GOT(frexp), LJ_ENDIAN_SELECT(-4,-8), DISPATCH_GL(tmptv), DISPATCH_GL(tmptv), (2+1)*8, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, DISPATCH_GOT(modf), LJ_ENDIAN_SELECT(-4,-8), (2+1)*8); + dasm_put(Dst, 2158, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM); + dasm_put(Dst, 2217, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, Dt5(->len), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), -LJ_TSTR, Dt5(->len), Dt5([1]), LJ_ENDIAN_SELECT(-4,-8), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 2276, LJ_TISNUM, DISPATCH_GOT(lj_str_new), Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 16+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM); + dasm_put(Dst, 2337, LJ_TSTR, Dt5(->len), sizeof(GCstr)-1, DISPATCH_GL(strempty), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), -LJ_TSTR, LJ_TISNUM, Dt5(->len), DISPATCH_GL(tmpbuf.sz)); + dasm_put(Dst, 2407, DISPATCH_GL(tmpbuf.buf), Dt5([1]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf)); + dasm_put(Dst, 2464, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold)); + dasm_put(Dst, 2527, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, DISPATCH_GL(tmpbuf.sz), Dt5(->len), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TTAB, DISPATCH_GOT(lj_tab_len), LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 2586, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 2649, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 2719, 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0)); + dasm_put(Dst, 2790, 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), 8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, Dt8(->f)); + dasm_put(Dst, 2863, LJ_ENDIAN_SELECT(-4,-8), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc), FRAME_TYPE, LJ_ENDIAN_SELECT(1,2), DISPATCH_GOT(lj_state_growstack), LUA_MINSTACK, Dt1(->base)); + dasm_put(Dst, 2931, DISPATCH_GOT(lj_gc_step), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-8,-4)); +#if LJ_HASJIT + dasm_put(Dst, 2957, DISPATCH_GL(hookmask), HOOK_VMEVENT, DISPATCH_GL(hookcount), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount)); +#endif + dasm_put(Dst, 2980, DISPATCH_GL(hookmask), HOOK_ACTIVE, GG_DISP2STATIC, DISPATCH_GL(hookmask), DISPATCH_GL(hookcount), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE, DISPATCH_GOT(lj_dispatch_ins), Dt1(->base), Dt1(->base)); + dasm_put(Dst, 3028, GG_DISP2STATIC, -24+LJ_ENDIAN_SELECT(0,4)); +#if LJ_HASJIT + dasm_put(Dst, 3047); +#endif + dasm_put(Dst, 3049); +#if LJ_HASJIT + dasm_put(Dst, 3051); +#endif + dasm_put(Dst, 3054); +#if LJ_HASJIT + dasm_put(Dst, 3057); +#endif + dasm_put(Dst, 3060, DISPATCH_GOT(lj_dispatch_call), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-8,-4)); +#if LJ_HASJIT + dasm_put(Dst, 3084); +#endif + dasm_put(Dst, 3086); +#if LJ_HASJIT + dasm_put(Dst, 3088); +#endif + dasm_put(Dst, 3090); +#if LJ_HASJIT + dasm_put(Dst, 3138); +#endif + dasm_put(Dst, 3161); +#if LJ_HASFFI +#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V) + dasm_put(Dst, 3163, 72+9*4, 72+8*4, 24+5*8, 72+7*4, 72+6*4, 24+4*8, 72+5*4, 72+4*4, 24+3*8, 72+3*4, 72+2*4, 24+2*8, 72+1*4, 72+0*4, 24+1*8, 24+0*8, Dt2(->ctype_state), GG_G2DISP, DISPATCH_GOT(lj_ccallback_enter), DtE(->cb.slot), DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.fpr[0])); + dasm_put(Dst, 3211, DtE(->cb.gpr[2]), DtE(->cb.gpr[3]), DtE(->cb.fpr[1]), 112+16, DtE(->cb.stack), Dt1(->base), Dt1(->top), LJ_ENDIAN_SELECT(-8,-4), ~LJ_VMST_INTERP, LJ_TNIL, DISPATCH_GL(vmstate), Dt7(->pc)); +#endif + dasm_put(Dst, 3255); +#if LJ_HASFFI + dasm_put(Dst, 3257, DISPATCH_GOT(lj_ccallback_leave), DISPATCH_GL(ctype_state), Dt1(->base), Dt1(->top), DtE(->L), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]), DtE(->cb.gpr[1]), DtE(->cb.fpr[1])); +#endif + dasm_put(Dst, 3281); +#if LJ_HASFFI +#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V) + dasm_put(Dst, 3283, DtF(->spadj), DtF(->nsp), offsetof(CCallState, stack), DtF(->func), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]), DtF(->fpr[0]), DtF(->fpr[1]), DtF(->gpr[0]), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->fpr[0]), DtF(->fpr[1])); +#endif +} + +/* Generate the code for a single instruction. */ +static void build_ins(BuildCtx *ctx, BCOp op, int defop) +{ + int vk = 0; + dasm_put(Dst, 3339, defop); + + switch (op) { + + /* -- Comparison ops ---------------------------------------------------- */ + + /* Remember: all ops branch for a true comparison, fall through otherwise. */ + + case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: + dasm_put(Dst, 3341, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_ENDIAN_SELECT(2,0), (-(BCBIAS_J*4 >> 16) & 65535)); + if (op == BC_ISLT || op == BC_ISGE) { + dasm_put(Dst, 3364); + } else { + dasm_put(Dst, 3366); + } + if (op == BC_ISLT || op == BC_ISLE) { + dasm_put(Dst, 3368); + } else { + dasm_put(Dst, 3370); + } + dasm_put(Dst, 3372); + break; + + case BC_ISEQV: case BC_ISNEV: + vk = op == BC_ISEQV; + dasm_put(Dst, 3386, LJ_ENDIAN_SELECT(4,0), -4+LJ_ENDIAN_SELECT(2,0), LJ_ENDIAN_SELECT(4,0), (-(BCBIAS_J*4 >> 16) & 65535), LJ_TISNUM, LJ_TISNUM); + if (vk) { + dasm_put(Dst, 3410); + } else { + dasm_put(Dst, 3412); + } + dasm_put(Dst, 3414, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(0,4)); + if (LJ_HASFFI) { + dasm_put(Dst, 3433, LJ_TCDATA); + } + dasm_put(Dst, 3438, LJ_TISPRI); + if (LJ_HASFFI) { + dasm_put(Dst, 3441); + } + dasm_put(Dst, 3444, LJ_TISTABUD+1); + if (vk) { + dasm_put(Dst, 3455); + } else { + dasm_put(Dst, 3457); + } + dasm_put(Dst, 3459, Dt6(->metatable), Dt6(->nomm), 1<> 16) & 65535)); + if (vk) { + dasm_put(Dst, 3502); + } else { + dasm_put(Dst, 3504); + } + dasm_put(Dst, 3506); + break; + + case BC_ISEQN: case BC_ISNEN: + vk = op == BC_ISEQN; + dasm_put(Dst, 3519, LJ_ENDIAN_SELECT(4,0), -4+LJ_ENDIAN_SELECT(2,0), (-(BCBIAS_J*4 >> 16) & 65535), LJ_TISNUM); + if (LJ_HASFFI) { + dasm_put(Dst, 3534); + } else { + dasm_put(Dst, 3537); + } + dasm_put(Dst, 3540); + if (vk) { + dasm_put(Dst, 3543); + } else { + dasm_put(Dst, 3547); + } + dasm_put(Dst, 3551); + if (LJ_HASFFI) { + dasm_put(Dst, 3563, LJ_TCDATA); + } + break; + + case BC_ISEQP: case BC_ISNEP: + vk = op == BC_ISEQP; + dasm_put(Dst, 3573, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(2,0)); + if (LJ_HASFFI) { + dasm_put(Dst, 3582, LJ_TCDATA); + } + dasm_put(Dst, 3587, (-(BCBIAS_J*4 >> 16) & 65535)); + if (vk) { + dasm_put(Dst, 3593); + } else { + dasm_put(Dst, 3595); + } + dasm_put(Dst, 3597); + break; + + /* -- Unary test and copy ops ------------------------------------------- */ + + case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF: + dasm_put(Dst, 3610, LJ_ENDIAN_SELECT(2,0), LJ_ENDIAN_SELECT(4,0)); + if (op == BC_IST || op == BC_ISF) { + dasm_put(Dst, 3617, LJ_TISTRUECOND, (-(BCBIAS_J*4 >> 16) & 65535)); + if (op == BC_IST) { + dasm_put(Dst, 3624); + } else { + dasm_put(Dst, 3626); + } + dasm_put(Dst, 3628); + } else { + dasm_put(Dst, 3630, LJ_TISTRUECOND); + if (op == BC_ISTC) { + dasm_put(Dst, 3634); + } else { + dasm_put(Dst, 3637); + } + dasm_put(Dst, 3640, (-(BCBIAS_J*4 >> 16) & 65535)); + } + dasm_put(Dst, 3649); + break; + + /* -- Unary ops --------------------------------------------------------- */ + + case BC_MOV: + dasm_put(Dst, 3661); + break; + case BC_NOT: + dasm_put(Dst, 3677, LJ_ENDIAN_SELECT(4,0), LJ_TFALSE, LJ_TISTRUECOND, LJ_TTRUE, LJ_ENDIAN_SELECT(4,0)); + break; + case BC_UNM: + dasm_put(Dst, 3701, LJ_ENDIAN_SELECT(4,0), LJ_TISNUM); + break; + case BC_LEN: + dasm_put(Dst, 3724, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TSTR, LJ_TTAB, Dt5(->len)); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 3758, Dt6(->metatable)); +#endif + dasm_put(Dst, 3765, DISPATCH_GOT(lj_tab_len)); +#ifdef LUAJIT_ENABLE_LUA52COMPAT + dasm_put(Dst, 3774, Dt6(->nomm), 1<base), DISPATCH_GOT(lj_meta_cat), Dt1(->base)); + break; + + /* -- Constant ops ------------------------------------------------------ */ + + case BC_KSTR: + dasm_put(Dst, 4170, LJ_TSTR, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0)); + break; + case BC_KCDATA: +#if LJ_HASFFI + dasm_put(Dst, 4192, LJ_TCDATA, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0)); +#endif + break; + case BC_KSHORT: + dasm_put(Dst, 4214); + break; + case BC_KNUM: + dasm_put(Dst, 4231); + break; + case BC_KPRI: + dasm_put(Dst, 4247, LJ_ENDIAN_SELECT(4,0)); + break; + case BC_KNIL: + dasm_put(Dst, 4264, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0)); + break; + + /* -- Upvalue and function ops ------------------------------------------ */ + + case BC_UGET: + dasm_put(Dst, 4288, LJ_ENDIAN_SELECT(-8,-4), Dt7(->uvptr), DtA(->v)); + break; + case BC_USETV: + dasm_put(Dst, 4311, LJ_ENDIAN_SELECT(-8,-4), Dt7(->uvptr), DtA(->marked), DtA(->v), LJ_GC_BLACK, DtA(->closed), LJ_ENDIAN_SELECT(4,0), LJ_GC_BLACK|1, -(LJ_TISNUM+1), LJ_TISGCV - (LJ_TISNUM+1), LJ_ENDIAN_SELECT(0,4), Dt4(->gch.marked), LJ_GC_WHITES, DISPATCH_GOT(lj_gc_barrieruv), GG_DISP2G); + break; + case BC_USETS: + dasm_put(Dst, 4371, LJ_ENDIAN_SELECT(-8,-4), Dt7(->uvptr), DtA(->marked), DtA(->v), Dt5(->marked), LJ_GC_BLACK, DtA(->closed), LJ_TSTR, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), LJ_GC_WHITES, DISPATCH_GOT(lj_gc_barrieruv), GG_DISP2G); + break; + case BC_USETN: + dasm_put(Dst, 4426, LJ_ENDIAN_SELECT(-8,-4), Dt7(->uvptr), DtA(->v)); + break; + case BC_USETP: + dasm_put(Dst, 4449, LJ_ENDIAN_SELECT(-8,-4), Dt7(->uvptr), DtA(->v), LJ_ENDIAN_SELECT(4,0)); + break; + + case BC_UCLO: + dasm_put(Dst, 4473, Dt1(->openupval), (-(BCBIAS_J*4 >> 16) & 65535), DISPATCH_GOT(lj_func_closeuv), Dt1(->base), Dt1(->base)); + break; + + case BC_FNEW: + dasm_put(Dst, 4504, DISPATCH_GOT(lj_func_newL_gc), LJ_ENDIAN_SELECT(-8,-4), Dt1(->base), Dt1(->base), LJ_TFUNC, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4)); + break; + + /* -- Table ops --------------------------------------------------------- */ + + case BC_TNEW: + case BC_TDUP: + dasm_put(Dst, 4537, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base)); + if (op == BC_TNEW) { + dasm_put(Dst, 4549, DISPATCH_GOT(lj_tab_new)); + } else { + dasm_put(Dst, 4560, DISPATCH_GOT(lj_tab_dup)); + } + dasm_put(Dst, 4568, Dt1(->base), LJ_TTAB, LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), DISPATCH_GOT(lj_gc_step_fixtop)); + break; + + case BC_GGET: + case BC_GSET: + dasm_put(Dst, 4598, LJ_ENDIAN_SELECT(-8,-4), Dt7(->env)); + if (op == BC_GGET) { + dasm_put(Dst, 4606); + } else { + dasm_put(Dst, 4609); + } + dasm_put(Dst, 4612); + break; + + case BC_TGETV: + dasm_put(Dst, 4614, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_TTAB, LJ_TISNUM, LJ_TSTR, Dt6(->asize), Dt6(->array), LJ_ENDIAN_SELECT(4,0), Dt6(->metatable), Dt6(->nomm), 1<hmask), Dt5(->hash), Dt6(->node), offsetof(Node, key)+LJ_ENDIAN_SELECT(4,0), offsetof(Node, key)+LJ_ENDIAN_SELECT(0,4), DtB(->next), offsetof(Node, val)+LJ_ENDIAN_SELECT(4,0), -LJ_TSTR, Dt6(->metatable), offsetof(Node, val)+LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4)); + dasm_put(Dst, 4764, LJ_TNIL, Dt6(->nomm), 1<asize), Dt6(->array), LJ_ENDIAN_SELECT(4,0), Dt6(->metatable), Dt6(->nomm), 1<asize), Dt6(->array), Dt6(->marked), LJ_ENDIAN_SELECT(4,0), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<marked), Dt6(->gclist)); + break; + case BC_TSETS: + dasm_put(Dst, 4939, LJ_ENDIAN_SELECT(4,0), LJ_TTAB, LJ_ENDIAN_SELECT(0,4), Dt6(->hmask), Dt5(->hash), Dt6(->node), Dt6(->nomm), offsetof(Node, key)+LJ_ENDIAN_SELECT(4,0), offsetof(Node, key)+LJ_ENDIAN_SELECT(0,4), LJ_TSTR, DtB(->next), offsetof(Node, val)+LJ_ENDIAN_SELECT(4,0), Dt6(->marked), Dt6(->metatable), LJ_GC_BLACK); + dasm_put(Dst, 4997, DtB(->val), Dt6(->nomm), 1<metatable), DISPATCH_GL(tmptv), Dt6(->nomm), 1<base), Dt1(->base)); + dasm_put(Dst, 5059, DISPATCH_GL(gc.grayagain), ~LJ_GC_BLACK & 255, DISPATCH_GL(gc.grayagain), Dt6(->marked), Dt6(->gclist)); + break; + case BC_TSETB: + dasm_put(Dst, 5076, LJ_ENDIAN_SELECT(4,0), LJ_TTAB, LJ_ENDIAN_SELECT(0,4), Dt6(->asize), Dt6(->array), LJ_ENDIAN_SELECT(4,0), Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->nomm), 1<marked), Dt6(->gclist)); + break; + + case BC_TSETM: + dasm_put(Dst, 5154, -8+LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(0,4), Dt6(->asize), Dt6(->marked), Dt6(->array), LJ_GC_BLACK, DISPATCH_GOT(lj_tab_reasize), Dt1(->base), Dt1(->base), DISPATCH_GL(gc.grayagain), ~LJ_GC_BLACK & 255, DISPATCH_GL(gc.grayagain), Dt6(->marked)); + dasm_put(Dst, 5227, Dt6(->gclist)); + break; + + /* -- Calls and vararg handling ----------------------------------------- */ + + case BC_CALLM: + dasm_put(Dst, 5232); + break; + case BC_CALL: + dasm_put(Dst, 5237, LJ_TFUNC, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(-4,-8), Dt7(->pc)); + break; + + case BC_CALLMT: + dasm_put(Dst, 5266); + break; + case BC_CALLT: + dasm_put(Dst, 5268, LJ_TFUNC, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(-4,-8), FRAME_TYPE, Dt7(->ffid), FRAME_VARG, LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc), -8+LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc)); + dasm_put(Dst, 5337, PC2PROTO(k), FRAME_TYPEP, LJ_ENDIAN_SELECT(-4,-8), FRAME_TYPE); + break; + + case BC_ITERC: + dasm_put(Dst, 5353, LJ_TFUNC, -24+LJ_ENDIAN_SELECT(4,0), -24+LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(-4,-8), Dt7(->pc)); + break; + + case BC_ITERN: +#if LJ_HASJIT +#endif + dasm_put(Dst, 5388, -16+LJ_ENDIAN_SELECT(0,4), -8+LJ_ENDIAN_SELECT(0,4), Dt6(->asize), Dt6(->array), LJ_ENDIAN_SELECT(4,0), -4+LJ_ENDIAN_SELECT(2,0), (-(BCBIAS_J*4 >> 16) & 65535), -8+LJ_ENDIAN_SELECT(0,4), Dt6(->hmask), Dt6(->node), LJ_ENDIAN_SELECT(4,0), -4+LJ_ENDIAN_SELECT(2,0), DtB(->key), (-(BCBIAS_J*4 >> 16) & 65535)); + dasm_put(Dst, 5470, -8+LJ_ENDIAN_SELECT(0,4)); + break; + + case BC_ISNEXT: + dasm_put(Dst, 5473, -24+LJ_ENDIAN_SELECT(4,0), -24+LJ_ENDIAN_SELECT(0,4), -16+LJ_ENDIAN_SELECT(4,0), -8+LJ_ENDIAN_SELECT(4,0), LJ_TFUNC, -LJ_TTAB, Dt8(->ffid), -LJ_TNIL, -FF_next_N, (-(BCBIAS_J*4 >> 16) & 65535), -8+LJ_ENDIAN_SELECT(0,4), BC_JMP, BC_ITERC, -4+LJ_ENDIAN_SELECT(0,3), LJ_ENDIAN_SELECT(0,3)); + break; + + case BC_VARG: + dasm_put(Dst, 5530, LJ_ENDIAN_SELECT(-4,-8), FRAME_VARG, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), Dt1(->maxstack), DISPATCH_GOT(lj_state_growstack), Dt1(->top), Dt1(->base), Dt1(->base)); + dasm_put(Dst, 5617); + break; + + /* -- Returns ----------------------------------------------------------- */ + + case BC_RETM: + dasm_put(Dst, 5619); + break; + + case BC_RET: + dasm_put(Dst, 5621, LJ_ENDIAN_SELECT(-4,-8), FRAME_TYPE, FRAME_VARG, LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc), PC2PROTO(k), LJ_ENDIAN_SELECT(4,0), FRAME_TYPEP, LJ_ENDIAN_SELECT(-4,-8)); + break; + + case BC_RET0: case BC_RET1: + dasm_put(Dst, 5693, LJ_ENDIAN_SELECT(-4,-8), FRAME_TYPE, FRAME_VARG); + if (op == BC_RET1) { + dasm_put(Dst, 5706); + } + dasm_put(Dst, 5708); + if (op == BC_RET1) { + dasm_put(Dst, 5713); + } + dasm_put(Dst, 5715, LJ_ENDIAN_SELECT(-8,-4), Dt7(->pc), PC2PROTO(k)); + if (op == BC_RET1) { + dasm_put(Dst, 5743, LJ_ENDIAN_SELECT(4,0)); + } else { + dasm_put(Dst, 5746, -8+LJ_ENDIAN_SELECT(4,0)); + } + break; + + /* -- Loops and branches ------------------------------------------------ */ + + case BC_FORL: +#if LJ_HASJIT + dasm_put(Dst, 5749); +#endif + break; + + case BC_JFORI: + case BC_JFORL: +#if !LJ_HASJIT + break; +#endif + case BC_FORI: + case BC_IFORL: + vk = (op == BC_IFORL || op == BC_JFORL); + dasm_put(Dst, 5751); + if (vk) { + dasm_put(Dst, 5753, FORL_IDX*8, FORL_STEP*8, FORL_STOP*8, FORL_STEP*8+LJ_ENDIAN_SELECT(4,0), FORL_IDX*8); + } else { + dasm_put(Dst, 5765, FORL_IDX*8+LJ_ENDIAN_SELECT(4,0), FORL_STEP*8+LJ_ENDIAN_SELECT(4,0), FORL_STOP*8+LJ_ENDIAN_SELECT(4,0), LJ_TISNUM, LJ_TISNUM, LJ_TISNUM, FORL_IDX*8, FORL_STOP*8); + } + if (op != BC_JFORL) { + dasm_put(Dst, 5786, (-(BCBIAS_J*4 >> 16) & 65535)); + } + dasm_put(Dst, 5790, FORL_EXT*8); + if (op == BC_JFORI) { + dasm_put(Dst, 5795, BC_JLOOP); + } else if (op == BC_JFORL) { + dasm_put(Dst, 5808, BC_JLOOP); + } else { + dasm_put(Dst, 5818); + if (op == BC_FORI) { + dasm_put(Dst, 5822); + } else { + dasm_put(Dst, 5825); + } + dasm_put(Dst, 5828); + } + dasm_put(Dst, 5831); + break; + + case BC_ITERL: +#if LJ_HASJIT + dasm_put(Dst, 5843); +#endif + break; + + case BC_JITERL: +#if !LJ_HASJIT + break; +#endif + case BC_IITERL: + dasm_put(Dst, 5845, LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4)); + if (op == BC_JITERL) { + dasm_put(Dst, 5853, -8+LJ_ENDIAN_SELECT(4,0), BC_JLOOP, -8+LJ_ENDIAN_SELECT(0,4)); + } else { + dasm_put(Dst, 5860, (-(BCBIAS_J*4 >> 16) & 65535), -8+LJ_ENDIAN_SELECT(4,0), -8+LJ_ENDIAN_SELECT(0,4)); + } + dasm_put(Dst, 5870); + break; + + case BC_LOOP: +#if LJ_HASJIT + dasm_put(Dst, 5883); +#endif + break; + + case BC_ILOOP: + dasm_put(Dst, 5885); + break; + + case BC_JLOOP: +#if LJ_HASJIT + dasm_put(Dst, 5897, DISPATCH_J(trace), DISPATCH_GL(vmstate), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L), DtD(->mcode), GG_DISP2G+32768); +#endif + break; + + case BC_JMP: + dasm_put(Dst, 5915, (-(BCBIAS_J*4 >> 16) & 65535)); + break; + + /* -- Function headers -------------------------------------------------- */ + + case BC_FUNCF: +#if LJ_HASJIT + dasm_put(Dst, 5932); +#endif + case BC_FUNCV: /* NYI: compiled vararg functions. */ + break; + + case BC_JFUNCF: +#if !LJ_HASJIT + break; +#endif + case BC_IFUNCF: + dasm_put(Dst, 5934, Dt1(->maxstack), -4+PC2PROTO(numparams), -4+PC2PROTO(k)); + if (op != BC_JFUNCF) { + dasm_put(Dst, 5945); + } + dasm_put(Dst, 5948); + if (op == BC_JFUNCF) { + dasm_put(Dst, 5954, BC_JLOOP); + } else { + dasm_put(Dst, 5959); + } + dasm_put(Dst, 5969, LJ_ENDIAN_SELECT(4,0)); + break; + + case BC_JFUNCV: +#if !LJ_HASJIT + break; +#endif + dasm_put(Dst, 5976); + break; /* NYI: compiled vararg functions. */ + + case BC_IFUNCV: + dasm_put(Dst, 5978, Dt1(->maxstack), LJ_ENDIAN_SELECT(0,4), 8+FRAME_VARG, -4+PC2PROTO(k), LJ_ENDIAN_SELECT(4,0), -4+PC2PROTO(numparams), LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(0,4), 8+LJ_ENDIAN_SELECT(0,4), 8+LJ_ENDIAN_SELECT(4,0), LJ_ENDIAN_SELECT(4,0)); + break; + + case BC_FUNCC: + case BC_FUNCCW: + if (op == BC_FUNCC) { + dasm_put(Dst, 6033, Dt8(->f)); + } else { + dasm_put(Dst, 6036, DISPATCH_GL(wrapf)); + } + dasm_put(Dst, 6039, Dt1(->maxstack), Dt1(->base), Dt1(->top), ~LJ_VMST_C); + if (op == BC_FUNCCW) { + dasm_put(Dst, 6051, Dt8(->f)); + } + dasm_put(Dst, 6054, DISPATCH_GL(vmstate), Dt1(->base), Dt1(->top), ~LJ_VMST_INTERP, LJ_ENDIAN_SELECT(-4,-8), DISPATCH_GL(vmstate)); + break; + + /* ---------------------------------------------------------------------- */ + + default: + fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]); + exit(2); + break; + } +} + +static int build_backend(BuildCtx *ctx) +{ + int op; + + dasm_growpc(Dst, BC__MAX); + + build_subroutines(ctx); + + dasm_put(Dst, 6075); + for (op = 0; op < BC__MAX; op++) + build_ins(ctx, (BCOp)op, op); + + return BC__MAX; +} + +/* Emit pseudo frame-info for all assembler functions. */ +static void emit_asm_debug(BuildCtx *ctx) +{ + int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code); + int i; + switch (ctx->mode) { + case BUILD_elfasm: + fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n"); + fprintf(ctx->fp, + ".Lframe0:\n" + "\t.4byte .LECIE0-.LSCIE0\n" + ".LSCIE0:\n" + "\t.4byte 0xffffffff\n" + "\t.byte 0x1\n" + "\t.string \"\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE0:\n\n"); + fprintf(ctx->fp, + ".LSFDE0:\n" + "\t.4byte .LEFDE0-.LASFDE0\n" + ".LASFDE0:\n" + "\t.4byte .Lframe0\n" + "\t.4byte .Lbegin\n" + "\t.4byte %d\n" + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x9f\n\t.sleb128 1\n" + "\t.byte 0x9e\n\t.sleb128 2\n", + fcofs, CFRAME_SIZE); + for (i = 23; i >= 16; i--) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); + for (i = 30; i >= 20; i -= 2) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE0:\n\n"); +#if LJ_HASFFI + fprintf(ctx->fp, + ".LSFDE1:\n" + "\t.4byte .LEFDE1-.LASFDE1\n" + ".LASFDE1:\n" + "\t.4byte .Lframe0\n" + "\t.4byte lj_vm_ffi_call\n" + "\t.4byte %d\n" + "\t.byte 0x9f\n\t.uleb128 1\n" + "\t.byte 0x90\n\t.uleb128 2\n" + "\t.byte 0xd\n\t.uleb128 0x10\n" + "\t.align 2\n" + ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); +#endif + fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n"); + fprintf(ctx->fp, + "\t.globl lj_err_unwind_dwarf\n" + ".Lframe1:\n" + "\t.4byte .LECIE1-.LSCIE1\n" + ".LSCIE1:\n" + "\t.4byte 0\n" + "\t.byte 0x1\n" + "\t.string \"zPR\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.uleb128 6\n" /* augmentation length */ + "\t.byte 0\n" + "\t.4byte lj_err_unwind_dwarf\n" + "\t.byte 0\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE1:\n\n"); + fprintf(ctx->fp, + ".LSFDE2:\n" + "\t.4byte .LEFDE2-.LASFDE2\n" + ".LASFDE2:\n" + "\t.4byte .LASFDE2-.Lframe1\n" + "\t.4byte .Lbegin\n" + "\t.4byte %d\n" + "\t.uleb128 0\n" /* augmentation length */ + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x9f\n\t.sleb128 1\n" + "\t.byte 0x9e\n\t.sleb128 2\n", + fcofs, CFRAME_SIZE); + for (i = 23; i >= 16; i--) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); + for (i = 30; i >= 20; i -= 2) + fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE2:\n\n"); +#if LJ_HASFFI + fprintf(ctx->fp, + ".Lframe2:\n" + "\t.4byte .LECIE2-.LSCIE2\n" + ".LSCIE2:\n" + "\t.4byte 0\n" + "\t.byte 0x1\n" + "\t.string \"zR\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 31\n" + "\t.uleb128 1\n" /* augmentation length */ + "\t.byte 0\n" + "\t.byte 0xc\n\t.uleb128 29\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE2:\n\n"); + fprintf(ctx->fp, + ".LSFDE3:\n" + "\t.4byte .LEFDE3-.LASFDE3\n" + ".LASFDE3:\n" + "\t.4byte .LASFDE3-.Lframe2\n" + "\t.4byte lj_vm_ffi_call\n" + "\t.4byte %d\n" + "\t.uleb128 0\n" /* augmentation length */ + "\t.byte 0x9f\n\t.uleb128 1\n" + "\t.byte 0x90\n\t.uleb128 2\n" + "\t.byte 0xd\n\t.uleb128 0x10\n" + "\t.align 2\n" + ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); +#endif + break; + default: + break; + } +} + diff --git a/src/lib_base.c b/src/lib_base.c index f8975986..1f8bb5fd 100644 --- a/src/lib_base.c +++ b/src/lib_base.c @@ -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) diff --git a/src/lj_arch.h b/src/lj_arch.h index 3a52c212..4b680306 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -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 diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 5ed1bf5b..97ad4f02 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c @@ -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))); diff --git a/src/lj_ccall.h b/src/lj_ccall.h index 0641625f..c94b6193 100644 --- a/src/lj_ccall.h +++ b/src/lj_ccall.h @@ -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 diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 3c95958d..d73153b1 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c @@ -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 diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 38fd1709..d99eb878 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c @@ -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 +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 diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h index c50d33ac..7dec0437 100644 --- a/src/lj_dispatch.h +++ b/src/lj_dispatch.h @@ -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. */ diff --git a/src/lj_frame.h b/src/lj_frame.h index a69917ee..8b2f3b4f 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h @@ -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" diff --git a/src/lj_target.h b/src/lj_target.h index c302d301..0dab8da4 100644 --- a/src/lj_target.h +++ b/src/lj_target.h @@ -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 diff --git a/src/lj_target_mips.h b/src/lj_target_mips.h new file mode 100644 index 00000000..88d066d6 --- /dev/null +++ b/src/lj_target_mips.h @@ -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 diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c index 8b177207..022e3ef2 100644 --- a/src/lj_vmmath.c +++ b/src/lj_vmmath.c @@ -10,7 +10,7 @@ #include #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