From 4eaf7f6efe7ea0bfafe8436321efe113834ad704 Mon Sep 17 00:00:00 2001 From: fsfod Date: Tue, 29 Mar 2016 12:15:55 +0100 Subject: [PATCH] Fix store opcodes with dynamic destructive out register not being correctly allocated an input register --- src/lj_asm.c | 2 +- src/lj_asm_x86.h | 2 +- src/lj_intrinsic.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lj_asm.c b/src/lj_asm.c index c01bf98e..99e691fb 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -2743,7 +2743,7 @@ static void wrap_intrins(jit_State *J, CIntrinsic *intrins, IntrinWrapState *sta /* Allocate the dynamic output register */ if (intrins->outsz > 0 && intrin_dynrout(intrins)) { - if (dynreg == DYNREG_INOUT) { + if (dynreg == DYNREG_INOUT || dynreg == DYNREG_TWOSTORE) { rout = reg_rid(in[1]); out[0] = reg_setrid(out[0], rout); } else if (dynreg == DYNREG_OPEXT) { diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index de637c29..0a803ee0 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h @@ -868,7 +868,7 @@ static void asm_intrin_opcode(ASMState *as, IRIns *ir, IntrinsInfo *ininfo) lua_assert(ra_hasreg(right) && (ra_hasreg(dest) || intrins->dyninsz < 2)); emit_intrins(as, intrins, right, dest, vvvv); - if (dynreg == DYNREG_INOUT) { + if (dynreg == DYNREG_INOUT || (dynreg == DYNREG_TWOSTORE && dynrout)) { lua_assert(lref); ra_left(as, dest, lref); /* no need to load the register since ra_left already did */ diff --git a/src/lj_intrinsic.h b/src/lj_intrinsic.h index ae095718..b9dbc953 100644 --- a/src/lj_intrinsic.h +++ b/src/lj_intrinsic.h @@ -28,7 +28,7 @@ typedef enum REGMODE { DYNREG_ONE, /* 1(R) register in, 1 out(M) which can be a memory address to store the value */ DYNREG_ONESTORE, - /* 2 in 0 out first must always be treated as indirect */ + /* 2 in with R optionally being destructive out. first must always be treated as indirect */ DYNREG_TWOSTORE, /* one input(M) register and the second is part of part of the opcode */ DYNREG_OPEXT,