Browse Source

PPC: Add skeleton for PowerPC interpreter.

Mike Pall 15 years ago
parent
commit
96b60d5ef3
1 changed files with 850 additions and 0 deletions
  1. 850 0
      src/buildvm_ppc.dasc

+ 850 - 0
src/buildvm_ppc.dasc

@@ -0,0 +1,850 @@
+|// Low-level VM code for PowerPC CPUs.
+|// Bytecode interpreter, fast functions and helper functions.
+|// Copyright (C) 2005-2010 Mike Pall. See Copyright Notice in luajit.h
+|
+|.arch ppc
+|.section code_op, code_sub
+|
+|.actionlist build_actionlist
+|.globals GLOB_
+|.globalnames globnames
+|.externnames extnames
+|
+|.if not SPE
+|.error "No support for plain PowerPC CPUs (yet)"
+|.endif
+|
+|//-----------------------------------------------------------------------
+|
+|// Trap for not-yet-implemented parts.
+|.macro NYI; tw 4, sp, sp; .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 PC2PROTO(field)  ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
+|
+|.macro hotloop
+|  NYI
+|.endmacro
+|
+|.macro hotcall
+|  NYI
+|.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:
+  |  NYI
+  |
+  |->vm_returnc:
+  |  NYI
+  |
+  |->vm_return:
+  |  NYI
+  |
+  |->vm_leave_cp:
+  |  NYI
+  |
+  |->vm_leave_unw:
+  |  NYI
+  |
+  |->vm_unwind_c:			// Unwind C stack, return from vm_pcall.
+  |  NYI
+  |->vm_unwind_c_eh:			// Landing pad for external unwinder.
+  |  NYI
+  |
+  |->vm_unwind_ff:			// Unwind C stack, return from ff pcall.
+  |  NYI
+  |->vm_unwind_ff_eh:			// Landing pad for external unwinder.
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Grow stack for calls -----------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |->vm_growstack_c:			// Grow stack for C function.
+  |  NYI
+  |
+  |->vm_growstack_l:			// Grow stack for Lua function.
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Entry points into the assembler VM ---------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |->vm_resume:				// Setup C frame and resume thread.
+  |  NYI
+  |
+  |->vm_pcall:				// Setup protected C frame and enter VM.
+  |  NYI
+  |
+  |->vm_call:				// Setup C frame and enter VM.
+  |  NYI
+  |
+  |->vm_call_dispatch:
+  |  NYI
+  |
+  |->vm_call_dispatch_f:
+  |  NYI
+  |
+  |->vm_cpcall:				// Setup protected C frame, call C.
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Metamethod handling ------------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |//-- Continuation dispatch ----------------------------------------------
+  |
+  |->cont_dispatch:
+  |  NYI
+  |
+  |->cont_cat:
+  |  NYI
+  |
+  |//-- Table indexing metamethods -----------------------------------------
+  |
+  |->vmeta_tgets:
+  |  NYI
+  |
+  |->vmeta_tgetb:
+  |  NYI
+  |
+  |->vmeta_tgetv:
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |
+  |->vmeta_tsets:
+  |  NYI
+  |
+  |->vmeta_tsetb:
+  |  NYI
+  |
+  |->vmeta_tsetv:
+  |  NYI
+  |
+  |//-- Comparison metamethods ---------------------------------------------
+  |
+  |->vmeta_comp:
+  |  NYI
+  |->cont_nop:
+  |  NYI
+  |
+  |->cont_ra:
+  |  NYI
+  |
+  |->cont_condt:
+  |  NYI
+  |
+  |->cont_condf:
+  |  NYI
+  |
+  |->vmeta_equal:
+  |  NYI
+  |
+  |//-- Arithmetic metamethods ---------------------------------------------
+  |
+  |->vmeta_arith_vn:
+  |  NYI
+  |
+  |->vmeta_arith_nv:
+  |  NYI
+  |
+  |->vmeta_unm:
+  |  NYI
+  |
+  |->vmeta_arith_vv:
+  |  NYI
+  |
+  |->vmeta_binop:
+  |  NYI
+  |
+  |->vmeta_len:
+  |  NYI
+  |
+  |//-- Call metamethod ----------------------------------------------------
+  |
+  |->vmeta_call_ra:
+  |  NYI
+  |
+  |->vmeta_call:			// Resolve and call __call metamethod.
+  |  NYI
+  |
+  |//-- Argument coercion for 'for' statement ------------------------------
+  |
+  |->vmeta_for:
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Fast functions -----------------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |.macro .ffunc, name
+  |->ff_ .. name:
+  |.endmacro
+  |
+  |.macro .ffunc_1, name
+  |->ff_ .. name:
+  |  NYI
+  |.endmacro
+  |
+  |.macro .ffunc_2, name
+  |->ff_ .. name:
+  |  NYI
+  |.endmacro
+  |
+  |.macro .ffunc_n, name
+  |  .ffunc_1 name
+  |  NYI
+  |.endmacro
+  |
+  |.macro .ffunc_nn, name
+  |  .ffunc_2 name
+  |  NYI
+  |.endmacro
+  |
+  |.macro ffgccheck
+  |  NYI
+  |.endmacro
+  |
+  |//-- Base library: checks -----------------------------------------------
+  |
+  |.ffunc assert
+  |  NYI
+  |
+  |.ffunc type
+  |  NYI
+  |
+  |//-- Base library: getters and setters ---------------------------------
+  |
+  |.ffunc_1 getmetatable
+  |  NYI
+  |
+  |.ffunc_2 setmetatable
+  |  NYI
+  |
+  |.ffunc_2 rawget
+  |  NYI
+  |
+  |//-- Base library: conversions ------------------------------------------
+  |
+  |.ffunc tonumber
+  |  NYI
+  |
+  |.ffunc_1 tostring
+  |  NYI
+  |
+  |//-- Base library: iterators -------------------------------------------
+  |
+  |.ffunc_1 next
+  |  NYI
+  |
+  |->fff_res2:
+  |  NYI
+  |
+  |.ffunc_1 pairs
+  |  NYI
+  |
+  |.ffunc_1 ipairs_aux
+  |  NYI
+  |
+  |->fff_res0:
+  |  NYI
+  |
+  |.ffunc_1 ipairs
+  |  NYI
+  |
+  |//-- Base library: catch errors ----------------------------------------
+  |
+  |.ffunc_1 pcall
+  |  NYI
+  |
+  |.ffunc_2 xpcall
+  |  NYI
+  |
+  |//-- Coroutine library --------------------------------------------------
+  |
+  |.macro coroutine_resume_wrap, resume
+  |.if resume
+  |.ffunc_1 coroutine_resume
+  |.else
+  |.ffunc coroutine_wrap_aux
+  |.endif
+  |  NYI
+  |.endmacro
+  |
+  |  coroutine_resume_wrap 1		// coroutine.resume
+  |  coroutine_resume_wrap 0		// coroutine.wrap
+  |
+  |.ffunc coroutine_yield
+  |  NYI
+  |
+  |//-- Math library -------------------------------------------------------
+  |
+  |.ffunc_n math_abs
+  |  NYI
+  |  // Fallthrough.
+  |
+  |->fff_res1:
+  |  NYI
+  |->fff_res:
+  |  NYI
+  |
+  |.macro math_extern, func
+  |  .ffunc math_ .. func
+  |  NYI
+  |.endmacro
+  |
+  |.macro math_extern2, func
+  |  .ffunc math_ .. func
+  |  NYI
+  |.endmacro
+  |
+  |  math_extern floor
+  |  math_extern ceil
+  |
+  |  math_extern sqrt
+  |  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 atan2
+  |  math_extern2 fmod
+  |
+  |->ff_math_deg:
+  |.ffunc_1 math_rad
+  |  NYI
+  |
+  |.ffunc_nn math_ldexp;	NYI
+  |.ffunc_n math_frexp;		NYI
+  |.ffunc_n math_modf;		NYI
+  |
+  |.ffunc_nn math_pow;		NYI
+  |
+  |.macro math_minmax, name, cmpop
+  |  .ffunc_1 name
+  |  NYI
+  |.endmacro
+  |
+  |  math_minmax math_min, efdtstlt
+  |  math_minmax math_max, efdtstgt
+  |
+  |//-- String library -----------------------------------------------------
+  |
+  |.ffunc_1 string_len
+  |  NYI
+  |
+  |.ffunc string_byte			// Only handle the 1-arg case here.
+  |  NYI
+  |
+  |.ffunc string_char			// Only handle the 1-arg case here.
+  |  NYI
+  |
+  |->fff_newstr:
+  |  NYI
+  |
+  |.ffunc string_sub
+  |  NYI
+  |
+  |->fff_emptystr:  // Range underflow.
+  |  NYI
+  |
+  |.ffunc_2 string_rep			// Only handle the 1-char case inline.
+  |  NYI
+  |
+  |.ffunc_1 string_reverse
+  |  NYI
+  |
+  |.macro ffstring_case, name, lo, hi
+  |  .ffunc_1 name
+  |  NYI
+  |.endmacro
+  |
+  |ffstring_case string_lower, 0x41, 0x5a
+  |ffstring_case string_upper, 0x61, 0x7a
+  |
+  |//-- Table library ------------------------------------------------------
+  |
+  |.ffunc_1 table_getn
+  |  NYI
+  |
+  |//-- Bit library --------------------------------------------------------
+  |
+  |.ffunc_n bit_tobit
+  |  NYI
+  |
+  |.macro .ffunc_bit, name
+  |  .ffunc_n name
+  |  NYI
+  |.endmacro
+  |
+  |.macro .ffunc_bit_op, name, ins
+  |  .ffunc_bit name
+  |  NYI
+  |.endmacro
+  |
+  |.ffunc_bit_op bit_band, and
+  |.ffunc_bit_op bit_bor, or
+  |.ffunc_bit_op bit_bxor, xor
+  |
+  |.ffunc_bit bit_bswap
+  |  NYI
+  |
+  |.ffunc_bit bit_bnot
+  |  NYI
+  |
+  |->fff_resbit:
+  |  NYI
+  |
+  |->fff_fallback_bit_op:
+  |  NYI
+  |
+  |.macro .ffunc_bit_sh, name, ins
+  |  .ffunc_nn name
+  |  NYI
+  |.endmacro
+  |
+  |.ffunc_bit_sh bit_lshift, shl
+  |.ffunc_bit_sh bit_rshift, shr
+  |.ffunc_bit_sh bit_arshift, sar
+  |.ffunc_bit_sh bit_rol, rol
+  |.ffunc_bit_sh bit_ror, ror
+  |
+  |//-----------------------------------------------------------------------
+  |
+  |->fff_fallback:			// Call fast function fallback handler.
+  |  NYI
+  |
+  |->fff_gcstep:			// Call GC step function.
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Special dispatch targets -------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |->vm_record:				// Dispatch target for recording phase.
+#if LJ_HASJIT
+  |  NYI
+#endif
+  |
+  |->vm_rethook:			// Dispatch target for return hooks.
+  |  NYI
+  |
+  |->vm_inshook:			// Dispatch target for instr/line hooks.
+  |  NYI
+  |
+  |->cont_hook:				// Continue from hook yield.
+  |  NYI
+  |
+  |->vm_hotloop:			// Hot loop counter underflow.
+#if LJ_HASJIT
+  |  NYI
+#endif
+  |
+  |->vm_callhook:			// Dispatch target for call hooks.
+  |  NYI
+  |
+  |->vm_hotcall:			// Hot call counter underflow.
+#if LJ_HASJIT
+  |  NYI
+#endif
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Trace exit handler -------------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |->vm_exit_handler:
+#if LJ_HASJIT
+  |  NYI
+#endif
+  |->vm_exit_interp:
+#if LJ_HASJIT
+  |  NYI
+#endif
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Math helper functions ----------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |// FP value rounding. Called by math.floor/math.ceil fast functions
+  |// and from JIT code.
+  |
+  |.macro vm_round, name, mode
+  |->name:
+  |  NYI
+  |.endmacro
+  |
+  |  vm_round vm_floor, 0
+  |  vm_round vm_ceil,  1
+  |  vm_round vm_trunc, 2
+  |
+  |->vm_mod:
+  |  NYI
+  |
+  |->vm_exp:
+  |  NYI
+  |->vm_exp2:
+  |  NYI
+  |
+  |->vm_pow:
+  |  NYI
+  |
+  |->vm_powi_sse:
+  |  NYI
+  |
+  |->vm_foldfpm:
+  |  NYI
+  |
+  |// Callable from C: double lj_vm_foldarith(double x, double y, int op)
+  |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
+  |// and basic math functions. ORDER ARITH
+  |->vm_foldarith:
+  |  NYI
+  |
+  |//-----------------------------------------------------------------------
+  |//-- Miscellaneous functions --------------------------------------------
+  |//-----------------------------------------------------------------------
+  |
+  |//-----------------------------------------------------------------------
+}
+
+/* Generate the code for a single instruction. */
+static void build_ins(BuildCtx *ctx, BCOp op, int defop)
+{
+  |=>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:
+    |  NYI
+    break;
+
+  case BC_ISEQV: case BC_ISNEV:
+    |  NYI
+    break;
+
+  case BC_ISEQS: case BC_ISNES:
+    |  NYI
+    break;
+
+  case BC_ISEQN: case BC_ISNEN:
+    |  NYI
+    break;
+
+  case BC_ISEQP: case BC_ISNEP:
+    |  NYI
+    break;
+
+  /* -- Unary test and copy ops ------------------------------------------- */
+
+  case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
+    |  NYI
+    break;
+
+  /* -- Unary ops --------------------------------------------------------- */
+
+  case BC_MOV:
+    |  NYI
+    break;
+  case BC_NOT:
+    |  NYI
+    break;
+  case BC_UNM:
+    |  NYI
+    break;
+  case BC_LEN:
+    |  NYI
+    break;
+
+  /* -- Binary ops -------------------------------------------------------- */
+
+  case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
+    |  NYI
+    break;
+  case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
+    |  NYI
+    break;
+  case BC_MULVN: case BC_MULNV: case BC_MULVV:
+    |  NYI
+    break;
+  case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
+    |  NYI
+    break;
+  case BC_MODVN:
+    |  NYI
+    break;
+  case BC_MODNV: case BC_MODVV:
+    |  NYI
+    break;
+  case BC_POW:
+    |  NYI
+    break;
+
+  case BC_CAT:
+    |  NYI
+    break;
+
+  /* -- Constant ops ------------------------------------------------------ */
+
+  case BC_KSTR:
+    |  NYI
+    break;
+  case BC_KSHORT:
+    |  NYI
+    break;
+  case BC_KNUM:
+    |  NYI
+    break;
+  case BC_KPRI:
+    |  NYI
+    break;
+  case BC_KNIL:
+    |  NYI
+    break;
+
+  /* -- Upvalue and function ops ------------------------------------------ */
+
+  case BC_UGET:
+    |  NYI
+    break;
+  case BC_USETV:
+    |  NYI
+    break;
+  case BC_USETS:
+    |  NYI
+    break;
+  case BC_USETN:
+    |  NYI
+    break;
+  case BC_USETP:
+    |  NYI
+    break;
+  case BC_UCLO:
+    |  NYI
+    break;
+
+  case BC_FNEW:
+    |  NYI
+    break;
+
+  /* -- Table ops --------------------------------------------------------- */
+
+  case BC_TNEW:
+    |  NYI
+    break;
+  case BC_TDUP:
+    |  NYI
+    break;
+
+  case BC_GGET:
+  case BC_GSET:
+    |  NYI
+    break;
+
+  case BC_TGETV:
+    |  NYI
+    break;
+  case BC_TGETS:
+    |  NYI
+    break;
+  case BC_TGETB:
+    |  NYI
+    break;
+
+  case BC_TSETV:
+    |  NYI
+    break;
+  case BC_TSETS:
+    |  NYI
+    break;
+  case BC_TSETB:
+    |  NYI
+    break;
+
+  case BC_TSETM:
+    |  NYI
+    break;
+
+  /* -- Calls and vararg handling ----------------------------------------- */
+
+  case BC_CALLM:
+    |  NYI
+    break;
+  case BC_CALL:
+    |  NYI
+    break;
+
+  case BC_CALLMT:
+    |  NYI
+    break;
+  case BC_CALLT:
+    |  NYI
+    break;
+
+  case BC_ITERC:
+    |  NYI
+    break;
+
+  case BC_VARG:
+    |  NYI
+    break;
+
+  /* -- Returns ----------------------------------------------------------- */
+
+  case BC_RETM:
+    |  NYI
+    break;
+
+  case BC_RET:
+    |  NYI
+    break;
+
+  case BC_RET0: case BC_RET1:
+    |  NYI
+    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:
+    |  NYI
+    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:
+    |  NYI
+    break;
+
+  case BC_LOOP:
+    |  NYI
+#if LJ_HASJIT
+    |  // Fall through. Assumes BC_ILOOP follows.
+#endif
+    break;
+
+  case BC_ILOOP:
+    |  NYI
+    break;
+
+  case BC_JLOOP:
+    |  NYI
+    break;
+
+  case BC_JMP:
+    |  hotcall
+    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:
+    |  NYI
+    break;
+
+  case BC_JFUNCV:
+#if !LJ_HASJIT
+    break;
+#endif
+    |  NYI  // NYI: compiled vararg functions
+    break;  /* NYI: compiled vararg functions. */
+
+  case BC_IFUNCV:
+    |  NYI
+    break;
+
+  case BC_FUNCC:
+  case BC_FUNCCW:
+    |  NYI
+    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)
+{
+  /* NYI */
+  UNUSED(ctx);
+}
+