Browse Source

Define x64 interpreter frame and cleanup use of stack temps.

Mike Pall 15 years ago
parent
commit
4cb357d30f
2 changed files with 175 additions and 106 deletions
  1. 157 88
      src/buildvm_x86.dasc
  2. 18 18
      src/buildvm_x86.h

+ 157 - 88
src/buildvm_x86.dasc

@@ -19,8 +19,13 @@
 |// Fixed register assignments for the interpreter.
 |// This is very fragile and has many dependencies. Caveat emptor.
 |.define BASE,		edx		// Not C callee-save, refetched anyway.
+|.if not X64 or X64WIN
 |.define KBASE,		edi		// Must be C callee-save.
 |.define PC,		esi		// Must be C callee-save.
+|.else
+|.define KBASE,		r13d		// Must be C callee-save.
+|.define PC,		r12d		// Must be C callee-save.
+|.endif
 |.define DISPATCH,	ebx		// Must be C callee-save.
 |
 |.define RA,		ecx
@@ -82,32 +87,23 @@
 |.macro pop_eax; .if X64; pop rax; .else; pop eax; .endif; .endmacro
 |
 |// Stack layout while in interpreter. Must match with lj_frame.h.
+|//-----------------------------------------------------------------------
+|.if not X64		// x86 stack layout.
+|
 |.define CFRAME_SPACE,	aword*7			// Delta for esp (see <--).
 |.macro saveregs
-|  .if X64
-|    .if X64WIN; push rdi; push rsi; .endif
-|    push rbp; push rbx; push r12; push r13; push r14; push r15
-|    sub rsp, CFRAME_SPACE
-|  .else
-|    push ebp; push edi; push esi; push ebx
-|    sub esp, CFRAME_SPACE
-|  .endif
+|  push ebp; push edi; push esi; push ebx
+|  sub esp, CFRAME_SPACE
 |.endmacro
 |.macro restoreregs
-|  .if X64
-|    add rsp, CFRAME_SPACE
-|    pop r15; pop r14; pop r13; pop r12; pop rbx; pop rbp
-|    .if X64WIN; pop rsi; pop rdi; .endif
-|  .else
-|    add esp, CFRAME_SPACE
-|    pop ebx; pop esi; pop edi; pop ebp
-|  .endif
+|  add esp, CFRAME_SPACE
+|  pop ebx; pop esi; pop edi; pop ebp
 |.endmacro
 |
-|.define INARG_4,	aword [esp+aword*15]
-|.define INARG_3,	aword [esp+aword*14]
-|.define INARG_2,	aword [esp+aword*13]
-|.define INARG_1,	aword [esp+aword*12]
+|.define SAVE_ERRF,	aword [esp+aword*15]	// vm_pcall/vm_cpcall only.
+|.define SAVE_NRES,	aword [esp+aword*14]
+|.define SAVE_CFRAME,	aword [esp+aword*13]
+|.define SAVE_L,	aword [esp+aword*12]
 |//----- 16 byte aligned, ^^^ arguments from C caller
 |.define SAVE_RET,	aword [esp+aword*11]	//<-- esp entering interpreter.
 |.define SAVE_R4,	aword [esp+aword*10]
@@ -116,8 +112,8 @@
 |//----- 16 byte aligned
 |.define SAVE_R1,	aword [esp+aword*7]	//<-- esp after register saves.
 |.define SAVE_PC,	aword [esp+aword*6]
-|.define ARG6,		aword [esp+aword*5]
-|.define ARG5,		aword [esp+aword*4]
+|.define TMP2,		aword [esp+aword*5]
+|.define TMP1,		aword [esp+aword*4]
 |//----- 16 byte aligned
 |.define ARG4,		aword [esp+aword*3]
 |.define ARG3,		aword [esp+aword*2]
@@ -126,24 +122,93 @@
 |//----- 16 byte aligned, ^^^ arguments for C callee
 |
 |// FPARGx overlaps ARGx and ARG(x+1) on x86.
-|.define FPARG5,	qword [esp+qword*2]
 |.define FPARG3,	qword [esp+qword*1]
 |.define FPARG1,	qword [esp]
-|// NRESULTS overlaps ARG6 (and FPARG5)
-|.define NRESULTS,	ARG6
+|// TMPQ overlaps TMP1/TMP2. ARG5/NRESULTS overlap TMP1/TMP2 (and TMPQ).
+|.define TMPQ,		qword [esp+aword*4]
+|.define ARG5,		TMP1
+|.define NRESULTS,	TMP2
 |
 |// Arguments for vm_call and vm_pcall.
-|.define INARG_P_ERRF,	INARG_4			// vm_pcall only.
-|.define INARG_NRES,	INARG_3
-|.define INARG_BASE,	INARG_2
-|.define SAVE_L,	INARG_1
-|
-|.define SAVE_CFRAME,	INARG_BASE		// Overwrites INARG_BASE!
+|.define INARG_BASE,	SAVE_CFRAME		// Overwritten by SAVE_CFRAME!
 |
 |// Arguments for vm_cpcall.
-|.define INARG_CP_UD,	INARG_4
-|.define INARG_CP_FUNC,	INARG_3
-|.define INARG_CP_CALL,	INARG_2
+|.define INARG_CP_UD,	SAVE_ERRF
+|.define INARG_CP_FUNC,	SAVE_NRES
+|.define INARG_CP_CALL,	SAVE_CFRAME
+|
+|//-----------------------------------------------------------------------
+|.elif X64WIN		// x64/Windows stack layout
+|
+|.define CFRAME_SPACE,	aword*5			// Delta for rsp (see <--).
+|.macro saveregs
+|  push rbp; push rdi; push rsi; push rbx
+|  sub rsp, CFRAME_SPACE
+|.endmacro
+|.macro restoreregs
+|  add rsp, CFRAME_SPACE
+|  pop rbx; pop rsi; pop rdi; pop rbp
+|.endmacro
+|
+|.define UNUSED1,	aword [esp+dword*26]
+|.define SAVE_PC,	dword [esp+dword*25]
+|.define SAVE_L,	dword [esp+dword*24]
+|.define SAVE_ERRF,	dword [esp+dword*23]
+|.define SAVE_NRES,	dword [esp+dword*22]
+|.define TMP2,		dword [esp+dword*21]
+|.define TMP1,		dword [esp+dword*20]
+|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by interpreter
+|.define SAVE_RET,	aword [esp+aword*9]	//<-- rsp entering interpreter.
+|.define SAVE_R4,	aword [esp+aword*8]
+|.define SAVE_R3,	aword [esp+aword*7]
+|.define SAVE_R2,	aword [esp+aword*6]
+|.define SAVE_R1,	aword [esp+aword*5]	//<-- rsp after register saves.
+|.define SAVE_CFRAME,	aword [esp+aword*4]
+|.define CSAVE_4,	aword [esp+aword*3]
+|.define CSAVE_3,	aword [esp+aword*2]
+|.define CSAVE_2,	aword [esp+aword*1]
+|.define CSAVE_1,	aword [esp]		//<-- rsp while in interpreter.
+|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
+|
+|// TMPQ overlaps TMP1/TMP2. NRESULTS overlaps TMP2 (and TMPQ).
+|.define TMPQ,		qword [esp]
+|.define NRESULTS,	TMP2
+|
+|//-----------------------------------------------------------------------
+|.else			// x64/POSIX stack layout
+|
+|.define CFRAME_SPACE,	aword*5			// Delta for rsp (see <--).
+|.macro saveregs
+|  push rbp; push r12; push r13; push rbx
+|  sub rsp, CFRAME_SPACE
+|.endmacro
+|.macro restoreregs
+|  add rsp, CFRAME_SPACE
+|  pop rbx; pop r13; pop r12; pop rbp
+|.endmacro
+|
+|//----- 16 byte aligned,
+|.define SAVE_RET,	aword [esp+aword*9]	//<-- rsp entering interpreter.
+|.define SAVE_R4,	aword [esp+aword*8]
+|.define SAVE_R3,	aword [esp+aword*7]
+|.define SAVE_R2,	aword [esp+aword*6]
+|.define SAVE_R1,	aword [esp+aword*5]	//<-- rsp after register saves.
+|.define SAVE_CFRAME,	aword [esp+aword*4]
+|.define UNUSED1,	aword [esp+aword*3]
+|//----- ^^^ awords above, vvv dwords below
+|.define SAVE_PC,	dword [esp+dword*5]
+|.define SAVE_L,	dword [esp+dword*4]
+|.define SAVE_ERRF,	dword [esp+dword*3]
+|.define SAVE_NRES,	dword [esp+dword*2]
+|.define TMP2,		dword [esp+dword*1]
+|.define TMP1,		dword [esp]		//<-- rsp while in interpreter.
+|//----- 16 byte aligned
+|
+|// TMPQ overlaps TMP1/TMP2. NRESULTS overlaps TMP2 (and TMPQ).
+|.define TMPQ,		qword [esp]
+|.define NRESULTS,	TMP2
+|
+|.endif
 |
 |//-----------------------------------------------------------------------
 |
@@ -163,7 +228,11 @@
 |  movzx OP, RCL
 |  add PC, 4
 |  shr RC, 16
+|.if not X64
 |  jmp aword [DISPATCH+OP*4]
+|.else
+|  jmp aword [DISPATCH+OP*8]
+|.endif
 |.endmacro
 |
 |// Instruction footer.
@@ -420,7 +489,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov L:RB->base, PC
   |3:
   |  mov RD, NRESULTS
-  |  mov RA, INARG_NRES			// RA = wanted nresults+1
+  |  mov RA, SAVE_NRES			// RA = wanted nresults+1
   |4:
   |  cmp RA, RD
   |  jne >6				// More/less results wanted?
@@ -633,8 +702,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  // Caveat: INARG_P_* and INARG_CP_* overlap!
   |  mov KBASE, L:RB->stack		// Compute -savestack(L, L->top).
   |  sub KBASE, L:RB->top
-  |  mov INARG_P_ERRF, 0		// No error function.
-  |  mov INARG_NRES, KBASE		// Neg. delta means cframe w/o frame.
+  |  mov SAVE_ERRF, 0			// No error function.
+  |  mov SAVE_NRES, KBASE		// Neg. delta means cframe w/o frame.
   |  // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
   |
   |  mov ARG3, RC
@@ -693,9 +762,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |//-- Table indexing metamethods -----------------------------------------
   |
   |->vmeta_tgets:
-  |  mov ARG5, RC			// RC = GCstr *
-  |  mov ARG6, LJ_TSTR
-  |  lea RC, ARG5			// Store temp. TValue in ARG5/ARG6.
+  |  mov TMP1, RC			// RC = GCstr *
+  |  mov TMP2, LJ_TSTR
+  |  lea RC, TMP1			// Store temp. TValue in TMP1/TMP2.
   |  cmp PC_OP, BC_GGET
   |  jne >1
   |  lea RA, [DISPATCH+DISPATCH_GL(tmptv)]  // Store fn->l.env in g->tmptv.
@@ -708,8 +777,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  movzx RC, PC_RC			// Ugly, cannot fild from a byte.
   |  mov ARG4, RC
   |  fild ARG4
-  |  fstp FPARG5
-  |  lea RC, ARG5			// Store temp. TValue in ARG5/ARG6.
+  |  fstp TMPQ
+  |  lea RC, TMP1			// Store temp. TValue in TMP1/TMP2.
   |  jmp >1
   |
   |->vmeta_tgetv:
@@ -751,9 +820,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |//-----------------------------------------------------------------------
   |
   |->vmeta_tsets:
-  |  mov ARG5, RC			// RC = GCstr *
-  |  mov ARG6, LJ_TSTR
-  |  lea RC, ARG5			// Store temp. TValue in ARG5/ARG6.
+  |  mov TMP1, RC			// RC = GCstr *
+  |  mov TMP2, LJ_TSTR
+  |  lea RC, TMP1			// Store temp. TValue in TMP1/TMP2.
   |  cmp PC_OP, BC_GSET
   |  jne >1
   |  lea RA, [DISPATCH+DISPATCH_GL(tmptv)]  // Store fn->l.env in g->tmptv.
@@ -766,8 +835,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  movzx RC, PC_RC			// Ugly, cannot fild from a byte.
   |  mov ARG4, RC
   |  fild ARG4
-  |  fstp FPARG5
-  |  lea RC, ARG5			// Store temp. TValue in ARG5/ARG6.
+  |  fstp TMPQ
+  |  lea RC, TMP1			// Store temp. TValue in TMP1/TMP2.
   |  jmp >1
   |
   |->vmeta_tsetv:
@@ -930,8 +999,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |->vmeta_call:			// Resolve and call __call metamethod.
   |  // RA = new base, RC = nargs+1, BASE = old base, PC = return
-  |  mov ARG4, RA			// Save RA, RC for us.
-  |  mov ARG5, NARGS:RC
+  |  mov TMP2, RA			// Save RA, RC for us.
+  |  mov TMP1, NARGS:RC
   |  sub RA, 8
   |  lea RC, [RA+NARGS:RC*8]
   |  mov L:RB, SAVE_L
@@ -942,8 +1011,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov L:RB->base, BASE		// This is the callers base!
   |  call extern lj_meta_call	// (lua_State *L, TValue *func, TValue *top)
   |  mov BASE, L:RB->base
-  |  mov RA, ARG4
-  |  mov NARGS:RC, ARG5
+  |  mov RA, TMP2
+  |  mov NARGS:RC, TMP1
   |  mov LFUNC:RB, [RA-8]
   |  add NARGS:RC, 1
   |  // This is fragile. L->base must not move, KBASE must always be defined.
@@ -1137,13 +1206,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov ARG2, TAB:RC
   |  mov ARG1, L:RB
   |  mov RB, RA
-  |  mov ARG4, BASE			// Save BASE and RA.
+  |  mov TMP1, BASE			// Save BASE and RA.
   |  add RA, 8
   |  mov ARG3, RA
   |  call extern lj_tab_get	// (lua_State *L, GCtab *t, cTValue *key)
   |  // cTValue * returned in eax (RC).
   |  mov RA, RB
-  |  mov BASE, ARG4
+  |  mov BASE, TMP1
   |  mov RB, [RC]			// Copy table slot.
   |  mov RC, [RC+4]
   |  mov [RA-8], RB
@@ -1199,13 +1268,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov L:RB->base, RA			// Add frame since C call can throw.
   |  mov [RA-4], PC
   |  mov SAVE_PC, PC			// Redundant (but a defined value).
-  |  mov ARG4, BASE			// Save BASE.
+  |  mov TMP1, BASE			// Save BASE.
   |  add RA, 8
   |  mov ARG3, RA
   |  call extern lj_tab_next	// (lua_State *L, GCtab *t, TValue *key)
   |  // Flag returned in eax (RC).
   |  mov RA, L:RB->base
-  |  mov BASE, ARG4
+  |  mov BASE, TMP1
   |  test RC, RC;  jz >3		// End of traversal?
   |  mov RB, [RA+8]			// Copy key and value to results.
   |  mov RC, [RA+12]
@@ -1526,11 +1595,11 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |.macro math_extern, func
   |.ffunc_n math_ .. func
-  |  mov ARG5, RA
+  |  mov TMP1, RA
   |  fstp FPARG1
   |  mov RB, BASE
   |  call extern lj_wrapper_ .. func
-  |  mov RA, ARG5
+  |  mov RA, TMP1
   |  mov BASE, RB
   |  jmp ->fff_resn
   |.endmacro
@@ -1645,10 +1714,10 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  cmp NARGS:RC, 1+1;  jne ->fff_fallback	// *Exactly* 1 arg.
   |  cmp dword [RA+4], LJ_TISNUM;  ja ->fff_fallback
   |  fld qword [RA]
-  |  fistp ARG4
-  |  cmp ARG4, 255;  ja ->fff_fallback
-  |  lea RC, ARG4			// Little-endian.
-  |  mov ARG5, RA			// Save RA.
+  |  fistp TMP2
+  |  cmp TMP2, 255;  ja ->fff_fallback
+  |  lea RC, TMP2			// Little-endian.
+  |  mov TMP1, RA			// Save RA.
   |  mov ARG3, 1
   |  mov ARG2, RC
   |->fff_newstr:
@@ -1658,7 +1727,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov L:RB->base, BASE
   |  call extern lj_str_new		// (lua_State *L, char *str, size_t l)
   |  // GCstr * returned in eax (RC).
-  |  mov RA, ARG5
+  |  mov RA, TMP1
   |  mov BASE, L:RB->base
   |  mov dword [RA-4], LJ_TSTR
   |  mov [RA-8], STR:RC
@@ -1666,13 +1735,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |.ffunc string_sub
   |  ffgccheck
-  |  mov ARG5, RA			// Save RA.
-  |  mov ARG4, -1
+  |  mov TMP1, RA			// Save RA.
+  |  mov TMP2, -1
   |  cmp NARGS:RC, 1+2;  jb ->fff_fallback
   |  jna >1
   |  cmp dword [RA+20], LJ_TISNUM;  ja ->fff_fallback
   |  fld qword [RA+16]
-  |  fistp ARG4
+  |  fistp TMP2
   |1:
   |  cmp dword [RA+4], LJ_TSTR;  jne ->fff_fallback
   |  cmp dword [RA+12], LJ_TISNUM;  ja ->fff_fallback
@@ -1681,7 +1750,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  mov RB, STR:RB->len
   |  fld qword [RA+8]
   |  fistp ARG3
-  |  mov RC, ARG4
+  |  mov RC, TMP2
   |  cmp RB, RC				// len < end? (unsigned compare)
   |  jb >5
   |2:
@@ -1722,13 +1791,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |.ffunc_2 string_rep			// Only handle the 1-char case inline.
   |  ffgccheck
-  |  mov ARG5, RA			// Save RA.
+  |  mov TMP1, RA			// Save RA.
   |  cmp dword [RA+4], LJ_TSTR;  jne ->fff_fallback
   |  cmp dword [RA+12], LJ_TISNUM;  ja ->fff_fallback
   |  mov STR:RB, [RA]
   |  fld qword [RA+8]
-  |  fistp ARG4
-  |  mov RC, ARG4
+  |  fistp TMP2
+  |  mov RC, TMP2
   |  test RC, RC
   |  jle ->fff_emptystr			// Count <= 0? (or non-int)
   |  cmp dword STR:RB->len, 1
@@ -1748,7 +1817,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |.ffunc_1 string_reverse
   |  ffgccheck
-  |  mov ARG5, RA			// Save RA.
+  |  mov TMP1, RA			// Save RA.
   |  cmp dword [RA+4], LJ_TSTR;  jne ->fff_fallback
   |  mov STR:RB, [RA]
   |  mov RC, STR:RB->len
@@ -1756,7 +1825,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  jz ->fff_emptystr			// Zero length string?
   |  cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC;  jb ->fff_fallback_1
   |  add RB, #STR
-  |  mov ARG4, PC			// Need another temp register.
+  |  mov TMP2, PC			// Need another temp register.
   |  mov ARG3, RC
   |  mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
   |  mov ARG2, PC
@@ -1766,19 +1835,19 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  sub RC, 1
   |  mov [PC+RC], RAL
   |  jnz <1
-  |  mov PC, ARG4
+  |  mov PC, TMP2
   |  jmp ->fff_newstr
   |
   |.macro ffstring_case, name, lo, hi
   |  .ffunc_1 name
   |  ffgccheck
-  |  mov ARG5, RA			// Save RA.
+  |  mov TMP1, RA			// Save RA.
   |  cmp dword [RA+4], LJ_TSTR;  jne ->fff_fallback
   |  mov STR:RB, [RA]
   |  mov RC, STR:RB->len
   |  cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC;  jb ->fff_fallback_1
   |  add RB, #STR
-  |  mov ARG4, PC			// Need another temp register.
+  |  mov TMP2, PC			// Need another temp register.
   |  mov ARG3, RC
   |  mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
   |  mov ARG2, PC
@@ -1795,7 +1864,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |3:
   |  sub RC, 1
   |  jns <1
-  |  mov PC, ARG4
+  |  mov PC, TMP2
   |  jmp ->fff_newstr
   |.endmacro
   |
@@ -1822,16 +1891,16 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |.define TOBIT_BIAS, 0x59c00000	// 2^52 + 2^51 (float, not double!).
   |
   |.ffunc_n bit_tobit
-  |  mov ARG5, TOBIT_BIAS
-  |  fadd ARG5
+  |  mov TMP1, TOBIT_BIAS
+  |  fadd TMP1
   |  fstp FPARG1			// 64 bit FP store.
   |  fild ARG1				// 32 bit integer load (s2lfwd ok).
   |  jmp ->fff_resn
   |
   |.macro .ffunc_bit, name
   |  .ffunc_n name
-  |  mov ARG5, TOBIT_BIAS
-  |  fadd ARG5
+  |  mov TMP1, TOBIT_BIAS
+  |  fadd TMP1
   |  fstp FPARG1
   |  mov RB, ARG1
   |.endmacro
@@ -1845,7 +1914,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |  jbe ->fff_resbit
   |  cmp dword [RC+4], LJ_TISNUM;  ja ->fff_fallback_bit_op
   |  fld qword [RC]
-  |  fadd ARG5
+  |  fadd TMP1
   |  fstp FPARG1
   |  ins RB, ARG1
   |  sub RC, 8
@@ -1873,10 +1942,10 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
   |
   |.macro .ffunc_bit_sh, name, ins
   |  .ffunc_nn name
-  |  mov ARG5, TOBIT_BIAS
-  |  fadd ARG5
+  |  mov TMP1, TOBIT_BIAS
+  |  fadd TMP1
   |  fstp FPARG3
-  |  fadd ARG5
+  |  fadd TMP1
   |  fstp FPARG1
   |  mov RC, RA				// Assumes RA is ecx.
   |  mov RA, ARG3
@@ -3121,9 +3190,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov)
     |  test byte TAB:RA->nomm, 1<<MM_newindex
     |  jz ->vmeta_tsets			// 'no __newindex' flag NOT set: check.
     |6:
-    |  mov ARG5, STR:RC
-    |  mov ARG6, LJ_TSTR
-    |  lea RC, ARG5			// Store temp. TValue in ARG5/ARG6.
+    |  mov TMP1, STR:RC
+    |  mov TMP2, LJ_TSTR
+    |  lea RC, TMP1			// Store temp. TValue in TMP1/TMP2.
     |  mov ARG4, TAB:RB			// Save TAB:RB for us.
     |  mov ARG2, TAB:RB
     |  mov L:RB, SAVE_L
@@ -3179,7 +3248,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov)
 
   case BC_TSETM:
     |  ins_AD	// RA = base (table at base-1), RD = num const (start index)
-    |  mov ARG5, KBASE			// Need one more free register.
+    |  mov TMP1, KBASE			// Need one more free register.
     |  fld qword [KBASE+RD*8]
     |  fistp ARG4			// Const is guaranteed to be an int.
     |1:
@@ -3208,7 +3277,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov)
     |  sub RD, 1
     |  jnz <3
     |4:
-    |  mov KBASE, ARG5
+    |  mov KBASE, TMP1
     |  ins_next
     |
     |5:  // Need to resize array part.

+ 18 - 18
src/buildvm_x86.h

@@ -103,9 +103,9 @@ static const unsigned char build_actionlist[12304] = {
   193,41,208,137,113,252,244,141,176,233,139,105,252,248,184,3,0,0,0,129,121,
   253,252,252,239,15,133,244,29,252,255,165,233,248,50,141,4,194,139,108,36,
   48,137,68,36,4,137,44,36,137,116,36,24,137,149,233,232,251,1,6,139,149,233,
-  252,233,244,42,248,29,137,76,36,12,137,68,36,16,131,252,233,8,141,4,193,139,
+  252,233,244,42,248,29,137,76,36,20,137,68,36,16,131,252,233,8,141,4,193,139,
   108,36,48,137,76,36,4,137,68,36,8,137,44,36,137,116,36,24,137,149,233,232,
-  251,1,7,139,149,233,139,76,36,12,139,68,36,16,139,105,252,248,131,192,1,57,
+  251,1,7,139,149,233,139,76,36,20,139,68,36,16,139,105,252,248,131,192,1,57,
   215,15,132,244,51,252,255,165,233,248,52,255,139,108,36,48,137,76,36,4,137,
   44,36,137,116,36,24,137,149,233,232,251,1,8,139,149,233,139,70,252,252,15,
   182,204,15,182,232,193,232,16,252,255,164,253,171,233,248,53,129,252,248,
@@ -129,8 +129,8 @@ static const unsigned char build_actionlist[12304] = {
   139,65,8,137,133,233,199,65,252,252,237,255,137,105,252,248,252,246,133,233,
   235,15,132,244,247,128,165,233,235,139,131,233,137,171,233,137,133,233,248,
   1,252,233,244,57,248,60,129,252,248,239,15,130,244,54,129,121,253,4,239,15,
-  133,244,54,139,1,139,108,36,48,137,68,36,4,137,44,36,137,205,137,84,36,12,
-  131,193,8,137,76,36,8,232,251,1,9,137,252,233,139,84,36,12,139,40,139,64,
+  133,244,54,139,1,139,108,36,48,137,68,36,4,137,44,36,137,205,137,84,36,16,
+  131,193,8,137,76,36,8,232,251,1,9,137,252,233,139,84,36,16,139,40,139,64,
   4,137,105,252,248,137,65,252,252,252,233,244,57,248,61,129,252,248,239,255,
   15,133,244,54,129,121,253,4,239,15,135,244,54,221,1,252,233,244,62,248,63,
   129,252,248,239,15,130,244,54,129,121,253,4,239,15,133,244,249,139,1,248,
@@ -140,8 +140,8 @@ static const unsigned char build_actionlist[12304] = {
   36,24,137,84,36,8,137,202,137,252,233,232,251,1,10,139,141,233,139,84,36,
   8,252,233,244,2,248,65,129,252,248,239,15,130,244,54,15,132,244,248,248,1,
   129,121,253,4,239,15,133,244,54,255,139,41,137,108,36,4,139,108,36,48,137,
-  44,36,137,141,233,137,113,252,252,137,116,36,24,137,84,36,12,131,193,8,137,
-  76,36,8,232,251,1,11,139,141,233,139,84,36,12,133,192,15,132,244,249,139,
+  44,36,137,141,233,137,113,252,252,137,116,36,24,137,84,36,16,131,193,8,137,
+  76,36,8,232,251,1,11,139,141,233,139,84,36,16,133,192,15,132,244,249,139,
   105,8,139,65,12,137,105,252,248,137,65,252,252,139,105,16,139,65,20,137,41,
   137,65,4,248,66,184,237,252,233,244,67,248,2,199,65,12,237,252,233,244,1,
   248,3,199,65,252,252,237,252,233,244,57,248,68,129,252,248,239,15,130,244,
@@ -261,43 +261,43 @@ static const unsigned char build_actionlist[12304] = {
   239,15,133,244,54,129,121,253,4,239,15,133,244,54,139,41,131,189,233,1,255,
   15,130,244,70,15,182,173,233,137,44,36,219,4,36,252,233,244,62,248,110,139,
   171,233,59,171,233,15,130,244,247,232,244,64,248,1,129,252,248,239,15,133,
-  244,54,129,121,253,4,239,15,135,244,54,221,1,219,92,36,12,129,124,36,12,252,
-  255,0,0,0,15,135,244,54,141,68,36,12,137,76,36,16,199,68,36,8,1,0,0,0,137,
+  244,54,129,121,253,4,239,15,135,244,54,221,1,219,92,36,20,129,124,36,20,252,
+  255,0,0,0,15,135,244,54,141,68,36,20,137,76,36,16,199,68,36,8,1,0,0,0,137,
   68,36,4,248,111,139,108,36,48,137,44,36,137,116,36,24,137,149,233,255,232,
   251,1,17,139,76,36,16,139,149,233,199,65,252,252,237,137,65,252,248,252,233,
   244,57,248,112,139,171,233,59,171,233,15,130,244,247,232,244,64,248,1,137,
-  76,36,16,199,68,36,12,252,255,252,255,252,255,252,255,129,252,248,239,15,
+  76,36,16,199,68,36,20,252,255,252,255,252,255,252,255,129,252,248,239,15,
   130,244,54,15,134,244,247,129,121,253,20,239,15,135,244,54,221,65,16,219,
-  92,36,12,248,1,129,121,253,4,239,15,133,244,54,255,129,121,253,12,239,15,
+  92,36,20,248,1,129,121,253,4,239,15,133,244,54,255,129,121,253,12,239,15,
   135,244,54,139,41,137,108,36,4,139,173,233,221,65,8,219,92,36,8,139,68,36,
-  12,57,197,15,130,244,251,248,2,139,76,36,8,133,201,15,142,244,253,248,3,139,
+  20,57,197,15,130,244,251,248,2,139,76,36,8,133,201,15,142,244,253,248,3,139,
   108,36,4,41,200,15,140,244,113,141,172,253,13,233,131,192,1,248,4,137,108,
   36,4,137,68,36,8,252,233,244,111,248,5,15,140,244,252,141,68,40,1,252,233,
   244,2,248,6,137,232,252,233,244,2,248,7,255,15,132,244,254,1,252,233,131,
   193,1,15,143,244,3,248,8,185,1,0,0,0,252,233,244,3,248,113,49,192,252,233,
   244,4,248,114,129,252,248,239,15,130,244,54,139,171,233,59,171,233,15,130,
   244,247,232,244,64,248,1,137,76,36,16,129,121,253,4,239,15,133,244,54,255,
-  129,121,253,12,239,15,135,244,54,139,41,221,65,8,219,92,36,12,139,68,36,12,
+  129,121,253,12,239,15,135,244,54,139,41,221,65,8,219,92,36,20,139,68,36,20,
   133,192,15,142,244,113,131,189,233,1,15,130,244,113,15,133,244,115,57,131,
   233,15,130,244,115,15,182,141,233,139,171,233,137,68,36,8,137,108,36,4,248,
   1,136,77,0,131,197,1,131,232,1,15,133,244,1,252,233,244,111,248,116,129,252,
   248,239,15,130,244,54,255,139,171,233,59,171,233,15,130,244,247,232,244,64,
   248,1,137,76,36,16,129,121,253,4,239,15,133,244,54,139,41,139,133,233,133,
-  192,15,132,244,113,57,131,233,15,130,244,117,129,197,239,137,116,36,12,137,
+  192,15,132,244,113,57,131,233,15,130,244,117,129,197,239,137,116,36,20,137,
   68,36,8,139,179,233,137,116,36,4,248,1,15,182,77,0,131,197,1,131,232,1,136,
-  12,6,15,133,244,1,139,116,36,12,252,233,244,111,248,118,255,129,252,248,239,
+  12,6,15,133,244,1,139,116,36,20,252,233,244,111,248,118,255,129,252,248,239,
   15,130,244,54,139,171,233,59,171,233,15,130,244,247,232,244,64,248,1,137,
   76,36,16,129,121,253,4,239,15,133,244,54,139,41,139,133,233,57,131,233,15,
-  130,244,117,129,197,239,137,116,36,12,137,68,36,8,139,179,233,137,116,36,
+  130,244,117,129,197,239,137,116,36,20,137,68,36,8,139,179,233,137,116,36,
   4,252,233,244,249,248,1,15,182,76,5,0,131,252,249,65,15,130,244,248,255,131,
   252,249,90,15,135,244,248,131,252,241,32,248,2,136,12,6,248,3,131,232,1,15,
-  137,244,1,139,116,36,12,252,233,244,111,248,119,129,252,248,239,15,130,244,
+  137,244,1,139,116,36,20,252,233,244,111,248,119,129,252,248,239,15,130,244,
   54,139,171,233,59,171,233,15,130,244,247,232,244,64,248,1,137,76,36,16,129,
   121,253,4,239,15,133,244,54,139,41,139,133,233,255,57,131,233,15,130,244,
-  117,129,197,239,137,116,36,12,137,68,36,8,139,179,233,137,116,36,4,252,233,
+  117,129,197,239,137,116,36,20,137,68,36,8,139,179,233,137,116,36,4,252,233,
   244,249,248,1,15,182,76,5,0,131,252,249,97,15,130,244,248,131,252,249,122,
   15,135,244,248,131,252,241,32,248,2,136,12,6,248,3,131,232,1,15,137,244,1,
-  139,116,36,12,252,233,244,111,248,120,129,252,248,239,15,130,244,54,129,121,
+  139,116,36,20,252,233,244,111,248,120,129,252,248,239,15,130,244,54,129,121,
   253,4,239,255,15,133,244,54,137,84,36,4,137,205,139,9,232,251,1,18,137,4,
   36,137,252,233,139,84,36,4,219,4,36,252,233,244,62,248,121,129,252,248,239,
   15,130,244,54,129,121,253,4,239,15,135,244,54,221,1,199,68,36,16,0,0,192,