#1 Add unreleased fixes and enhancements from upstream and github fork
Merged 5 years ago by ignatenkobrain. Opened 5 years ago by siddhesh.
rpms/ siddhesh/luajit master  into  master

@@ -0,0 +1,31 @@ 

+ commit 31afda31814ec02f82ffb0519bee496c87eeaa89

+ Merge: 8271c64 1c89933

+ Author: Mike Pall <mike>

+ Date:   Tue May 9 21:01:23 2017 +0200

+ 

+     Merge branch 'master' into v2.1

+ 

+ commit 1c89933f129dde76944336c6bfd05297b8d67730

+ Author: Mike Pall <mike>

+ Date:   Tue May 9 20:59:37 2017 +0200

+ 

+     Fix LJ_MAX_JSLOTS assertion in rec_check_slots().

+     

+     Thanks to Yichun Zhang.

+ 

+ diff --git a/src/lj_record.c b/src/lj_record.c

+ index 9d0469c..c2d0274 100644

+ --- a/src/lj_record.c

+ +++ b/src/lj_record.c

+ @@ -87,9 +87,9 @@ static void rec_check_slots(jit_State *J)

+    BCReg s, nslots = J->baseslot + J->maxslot;

+    int32_t depth = 0;

+    cTValue *base = J->L->base - J->baseslot;

+ -  lua_assert(J->baseslot >= 1+LJ_FR2 && J->baseslot < LJ_MAX_JSLOTS);

+ +  lua_assert(J->baseslot >= 1+LJ_FR2);

+    lua_assert(J->baseslot == 1+LJ_FR2 || (J->slot[J->baseslot-1] & TREF_FRAME));

+ -  lua_assert(nslots < LJ_MAX_JSLOTS);

+ +  lua_assert(nslots <= LJ_MAX_JSLOTS);

+    for (s = 0; s < nslots; s++) {

+      TRef tr = J->slot[s];

+      if (tr) {

@@ -0,0 +1,40 @@ 

+ commit 6259c0b909a8c00fabe3c7e6bd81150ee08cbf9f

+ Merge: 31afda3 630ff31

+ Author: Mike Pall <mike>

+ Date:   Wed May 17 17:38:53 2017 +0200

+ 

+     Merge branch 'master' into v2.1

+ 

+ commit 630ff3196a06353c6a7ccd1e9ac3958f4a8ca13c

+ Author: Mike Pall <mike>

+ Date:   Wed May 17 17:37:35 2017 +0200

+ 

+     Add missing LJ_MAX_JSLOTS check.

+     

+     Thanks to Yichun Zhang.

+ 

+ From 630ff3196a06353c6a7ccd1e9ac3958f4a8ca13c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 17 May 2017 17:37:35 +0200

+ Subject: [PATCH 02/72] Add missing LJ_MAX_JSLOTS check.

+ 

+ Thanks to Yichun Zhang.

+ ---

+  src/lj_record.c | 2 ++

+  1 file changed, 2 insertions(+)

+ 

+ diff --git a/src/lj_record.c b/src/lj_record.c

+ index cecacd2..bc4e8a6 100644

+ --- a/src/lj_record.c

+ +++ b/src/lj_record.c

+ @@ -633,6 +633,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)

+    J->framedepth++;

+    J->base += func+1+LJ_FR2;

+    J->baseslot += func+1+LJ_FR2;

+ +  if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)

+ +    lj_trace_err(J, LJ_TRERR_STACKOV);

+  }

+  

+  /* Record tail call. */

+ -- 

+ 2.20.1

@@ -0,0 +1,30 @@ 

+ From 7381b620358c2561e8690149f1d25828fdad6675 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 7 Jun 2017 19:16:22 +0200

+ Subject: [PATCH 03/72] MIPS: Use precise search for exit jump patching.

+ 

+ Contributed by Djordje Kovacevic and Stefan Pejic.

+ ---

+  src/lj_asm_mips.h | 6 +++++-

+  1 file changed, 5 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h

+ index 03270cc..d0a1ca5 100644

+ --- a/src/lj_asm_mips.h

+ +++ b/src/lj_asm_mips.h

+ @@ -1933,7 +1933,11 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)

+    MCode tjump = MIPSI_J|(((uintptr_t)target>>2)&0x03ffffffu);

+    for (p++; p < pe; p++) {

+      if (*p == exitload) {  /* Look for load of exit number. */

+ -      if (((p[-1] ^ (px-p)) & 0xffffu) == 0) {  /* Look for exitstub branch. */

+ +      /* Look for exitstub branch. Yes, this covers all used branch variants. */

+ +      if (((p[-1] ^ (px-p)) & 0xffffu) == 0 &&

+ +	  ((p[-1] & 0xf0000000u) == MIPSI_BEQ ||

+ +	   (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ ||

+ +	   (p[-1] & 0xffe00000u) == MIPSI_BC1F)) {

+  	ptrdiff_t delta = target - p;

+  	if (((delta + 0x8000) >> 16) == 0) {  /* Patch in-range branch. */

+  	patchbranch:

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,77 @@ 

+ From c7c3c4da432ddb543d4b0a9abbb245f11b26afd0 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 7 Jun 2017 19:36:46 +0200

+ Subject: [PATCH 04/72] MIPS: Fix handling of spare long-range jump slots.

+ 

+ Contributed by Djordje Kovacevic and Stefan Pejic.

+ ---

+  src/lj_asm_mips.h | 9 +++++----

+  src/lj_jit.h      | 6 ++++++

+  src/lj_mcode.c    | 6 ------

+  3 files changed, 11 insertions(+), 10 deletions(-)

+ 

+ diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h

+ index d0a1ca5..7631190 100644

+ --- a/src/lj_asm_mips.h

+ +++ b/src/lj_asm_mips.h

+ @@ -65,10 +65,9 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)

+  static void asm_sparejump_setup(ASMState *as)

+  {

+    MCode *mxp = as->mcbot;

+ -  /* Assumes sizeof(MCLink) == 8. */

+ -  if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == 8) {

+ +  if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {

+      lua_assert(MIPSI_NOP == 0);

+ -    memset(mxp+2, 0, MIPS_SPAREJUMP*8);

+ +    memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode));

+      mxp += MIPS_SPAREJUMP*2;

+      lua_assert(mxp < as->mctop);

+      lj_mcode_sync(as->mcbot, mxp);

+ @@ -1947,7 +1946,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)

+  	  if (!cstart) cstart = p-1;

+  	} else {  /* Branch out of range. Use spare jump slot in mcarea. */

+  	  int i;

+ -	  for (i = 2; i < 2+MIPS_SPAREJUMP*2; i += 2) {

+ +	  for (i = (int)(sizeof(MCLink)/sizeof(MCode));

+ +	       i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2);

+ +	       i += 2) {

+  	    if (mcarea[i] == tjump) {

+  	      delta = mcarea+i - p;

+  	      goto patchbranch;

+ diff --git a/src/lj_jit.h b/src/lj_jit.h

+ index a2e8fd9..3f38d28 100644

+ --- a/src/lj_jit.h

+ +++ b/src/lj_jit.h

+ @@ -155,6 +155,12 @@ typedef uint8_t MCode;

+  typedef uint32_t MCode;

+  #endif

+  

+ +/* Linked list of MCode areas. */

+ +typedef struct MCLink {

+ +  MCode *next;		/* Next area. */

+ +  size_t size;		/* Size of current area. */

+ +} MCLink;

+ +

+  /* Stack snapshot header. */

+  typedef struct SnapShot {

+    uint16_t mapofs;	/* Offset into snapshot map. */

+ diff --git a/src/lj_mcode.c b/src/lj_mcode.c

+ index f0a1f69..5ea89f6 100644

+ --- a/src/lj_mcode.c

+ +++ b/src/lj_mcode.c

+ @@ -272,12 +272,6 @@ static void *mcode_alloc(jit_State *J, size_t sz)

+  

+  /* -- MCode area management ----------------------------------------------- */

+  

+ -/* Linked list of MCode areas. */

+ -typedef struct MCLink {

+ -  MCode *next;		/* Next area. */

+ -  size_t size;		/* Size of current area. */

+ -} MCLink;

+ -

+  /* Allocate a new MCode area. */

+  static void mcode_allocarea(jit_State *J)

+  {

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,982 @@ 

+ From a057a07ab702e225e21848d4f918886c5b0ac06b Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 7 Jun 2017 23:56:54 +0200

+ Subject: [PATCH 05/72] MIPS64: Add soft-float support to JIT compiler backend.

+ 

+ Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.

+ Sponsored by Cisco Systems, Inc.

+ ---

+  src/lj_arch.h      |   4 +-

+  src/lj_asm.c       |   8 +-

+  src/lj_asm_mips.h  | 217 +++++++++++++++++++++++++++++++++++++--------

+  src/lj_crecord.c   |   4 +-

+  src/lj_emit_mips.h |   2 +

+  src/lj_ffrecord.c  |   2 +-

+  src/lj_ircall.h    |  43 ++++++---

+  src/lj_iropt.h     |   2 +-

+  src/lj_jit.h       |   4 +-

+  src/lj_obj.h       |   3 +

+  src/lj_opt_split.c |   2 +-

+  src/lj_snap.c      |  21 +++--

+  src/vm_mips64.dasc |  49 ++++++++++

+  13 files changed, 286 insertions(+), 75 deletions(-)

+ 

+ diff --git a/src/lj_arch.h b/src/lj_arch.h

+ index c8d7138..b770564 100644

+ --- a/src/lj_arch.h

+ +++ b/src/lj_arch.h

+ @@ -337,9 +337,6 @@

+  #define LJ_ARCH_BITS		32

+  #define LJ_TARGET_MIPS32	1

+  #else

+ -#if LJ_ABI_SOFTFP || !LJ_ARCH_HASFPU

+ -#define LJ_ARCH_NOJIT		1	/* NYI */

+ -#endif

+  #define LJ_ARCH_BITS		64

+  #define LJ_TARGET_MIPS64	1

+  #define LJ_TARGET_GC64		1

+ @@ -512,6 +509,7 @@

+  #define LJ_ABI_SOFTFP		0

+  #endif

+  #define LJ_SOFTFP		(!LJ_ARCH_HASFPU)

+ +#define LJ_SOFTFP32		(LJ_SOFTFP && LJ_32)

+  

+  #if LJ_ARCH_ENDIAN == LUAJIT_BE

+  #define LJ_LE			0

+ diff --git a/src/lj_asm.c b/src/lj_asm.c

+ index c2cf5a9..bed2268 100644

+ --- a/src/lj_asm.c

+ +++ b/src/lj_asm.c

+ @@ -338,7 +338,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)

+    ra_modified(as, r);

+    ir->r = RID_INIT;  /* Do not keep any hint. */

+    RA_DBGX((as, "remat     $i $r", ir, r));

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+    if (ir->o == IR_KNUM) {

+      emit_loadk64(as, r, ir);

+    } else

+ @@ -1305,7 +1305,7 @@ static void asm_call(ASMState *as, IRIns *ir)

+    asm_gencall(as, ci, args);

+  }

+  

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+  static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)

+  {

+    const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];

+ @@ -1652,10 +1652,10 @@ static void asm_ir(ASMState *as, IRIns *ir)

+    case IR_MUL: asm_mul(as, ir); break;

+    case IR_MOD: asm_mod(as, ir); break;

+    case IR_NEG: asm_neg(as, ir); break;

+ -#if LJ_SOFTFP

+ +#if LJ_SOFTFP32

+    case IR_DIV: case IR_POW: case IR_ABS:

+    case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:

+ -    lua_assert(0);  /* Unused for LJ_SOFTFP. */

+ +    lua_assert(0);  /* Unused for LJ_SOFTFP32. */

+      break;

+  #else

+    case IR_DIV: asm_div(as, ir); break;

+ diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h

+ index 05af3d0..1406a87 100644

+ --- a/src/lj_asm_mips.h

+ +++ b/src/lj_asm_mips.h

+ @@ -290,7 +290,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+  	  {

+  	    ra_leftov(as, gpr, ref);

+  	    gpr++;

+ -#if LJ_64

+ +#if LJ_64 && !LJ_SOFTFP

+  	    fpr++;

+  #endif

+  	  }

+ @@ -301,7 +301,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+  	  emit_spstore(as, ir, r, ofs);

+  	  ofs += irt_isnum(ir->t) ? 8 : 4;

+  #else

+ -	  emit_spstore(as, ir, r, ofs + ((LJ_BE && (LJ_SOFTFP || r < RID_MAX_GPR) && !irt_is64(ir->t)) ? 4 : 0));

+ +	  emit_spstore(as, ir, r, ofs + ((LJ_BE && !irt_isfp(ir->t) && !irt_is64(ir->t)) ? 4 : 0));

+  	  ofs += 8;

+  #endif

+  	}

+ @@ -312,7 +312,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+  #endif

+        if (gpr <= REGARG_LASTGPR) {

+  	gpr++;

+ -#if LJ_64

+ +#if LJ_64 && !LJ_SOFTFP

+  	fpr++;

+  #endif

+        } else {

+ @@ -461,12 +461,36 @@ static void asm_tobit(ASMState *as, IRIns *ir)

+    emit_tg(as, MIPSI_MFC1, dest, tmp);

+    emit_fgh(as, MIPSI_ADD_D, tmp, left, right);

+  }

+ +#elif LJ_64  /* && LJ_SOFTFP */

+ +static void asm_tointg(ASMState *as, IRIns *ir, Reg r)

+ +{

+ +  /* The modified regs must match with the *.dasc implementation. */

+ +  RegSet drop = RID2RSET(REGARG_FIRSTGPR)|RID2RSET(RID_RET)|RID2RSET(RID_RET+1)|

+ +		RID2RSET(RID_R1)|RID2RSET(RID_R12);

+ +  if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);

+ +  ra_evictset(as, drop);

+ +  /* Return values are in RID_RET (converted value) and RID_RET+1 (status). */

+ +  ra_destreg(as, ir, RID_RET);

+ +  asm_guard(as, MIPSI_BNE, RID_RET+1, RID_ZERO);

+ +  emit_call(as, (void *)lj_ir_callinfo[IRCALL_lj_vm_tointg].func, 0);

+ +  if (r == RID_NONE)

+ +    ra_leftov(as, REGARG_FIRSTGPR, ir->op1);

+ +  else if (r != REGARG_FIRSTGPR)

+ +    emit_move(as, REGARG_FIRSTGPR, r);

+ +}

+ +

+ +static void asm_tobit(ASMState *as, IRIns *ir)

+ +{

+ +  Reg dest = ra_dest(as, ir, RSET_GPR);

+ +  emit_dta(as, MIPSI_SLL, dest, dest, 0);

+ +  asm_callid(as, ir, IRCALL_lj_vm_tobit);

+ +}

+  #endif

+  

+  static void asm_conv(ASMState *as, IRIns *ir)

+  {

+    IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+    int stfp = (st == IRT_NUM || st == IRT_FLOAT);

+  #endif

+  #if LJ_64

+ @@ -477,12 +501,13 @@ static void asm_conv(ASMState *as, IRIns *ir)

+    lua_assert(!(irt_isint64(ir->t) ||

+  	       (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */

+  #endif

+ -#if LJ_32 && LJ_SOFTFP

+ +#if LJ_SOFTFP32

+    /* FP conversions are handled by SPLIT. */

+    lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));

+    /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */

+  #else

+    lua_assert(irt_type(ir->t) != st);

+ +#if !LJ_SOFTFP

+    if (irt_isfp(ir->t)) {

+      Reg dest = ra_dest(as, ir, RSET_FPR);

+      if (stfp) {  /* FP to FP conversion. */

+ @@ -608,6 +633,42 @@ static void asm_conv(ASMState *as, IRIns *ir)

+        }

+      }

+    } else

+ +#else

+ +  if (irt_isfp(ir->t)) {

+ +#if LJ_64 && LJ_HASFFI

+ +    if (stfp) {  /* FP to FP conversion. */

+ +      asm_callid(as, ir, irt_isnum(ir->t) ? IRCALL_softfp_f2d :

+ +					    IRCALL_softfp_d2f);

+ +    } else {  /* Integer to FP conversion. */

+ +      IRCallID cid = ((IRT_IS64 >> st) & 1) ?

+ +	(irt_isnum(ir->t) ?

+ +	 (st == IRT_I64 ? IRCALL_fp64_l2d : IRCALL_fp64_ul2d) :

+ +	 (st == IRT_I64 ? IRCALL_fp64_l2f : IRCALL_fp64_ul2f)) :

+ +	(irt_isnum(ir->t) ?

+ +	 (st == IRT_INT ? IRCALL_softfp_i2d : IRCALL_softfp_ui2d) :

+ +	 (st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f));

+ +      asm_callid(as, ir, cid);

+ +    }

+ +#else

+ +    asm_callid(as, ir, IRCALL_softfp_i2d);

+ +#endif

+ +  } else if (stfp) {  /* FP to integer conversion. */

+ +    if (irt_isguard(ir->t)) {

+ +      /* Checked conversions are only supported from number to int. */

+ +      lua_assert(irt_isint(ir->t) && st == IRT_NUM);

+ +      asm_tointg(as, ir, RID_NONE);

+ +    } else {

+ +      IRCallID cid = irt_is64(ir->t) ?

+ +	((st == IRT_NUM) ?

+ +	 (irt_isi64(ir->t) ? IRCALL_fp64_d2l : IRCALL_fp64_d2ul) :

+ +	 (irt_isi64(ir->t) ? IRCALL_fp64_f2l : IRCALL_fp64_f2ul)) :

+ +	((st == IRT_NUM) ?

+ +	 (irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) :

+ +	 (irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui));

+ +      asm_callid(as, ir, cid);

+ +    }

+ +  } else

+ +#endif

+  #endif

+    {

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+ @@ -665,7 +726,7 @@ static void asm_strto(ASMState *as, IRIns *ir)

+    const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];

+    IRRef args[2];

+    int32_t ofs = 0;

+ -#if LJ_SOFTFP

+ +#if LJ_SOFTFP32

+    ra_evictset(as, RSET_SCRATCH);

+    if (ra_used(ir)) {

+      if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&

+ @@ -806,7 +867,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+    MCLabel l_end, l_loop, l_next;

+  

+    rset_clear(allow, tab);

+ -#if LJ_32 && LJ_SOFTFP

+ +#if LJ_SOFTFP32

+    if (!isk) {

+      key = ra_alloc1(as, refkey, allow);

+      rset_clear(allow, key);

+ @@ -826,7 +887,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+      }

+    }

+  #else

+ -  if (irt_isnum(kt)) {

+ +  if (!LJ_SOFTFP && irt_isnum(kt)) {

+      key = ra_alloc1(as, refkey, RSET_FPR);

+      tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));

+    } else if (!irt_ispri(kt)) {

+ @@ -882,6 +943,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+      emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);

+      emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);

+      emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));

+ +  } else if (LJ_SOFTFP && irt_isnum(kt)) {

+ +    emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);

+ +    emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));

+    } else if (irt_isaddr(kt)) {

+      Reg refk = tmp2;

+      if (isk) {

+ @@ -960,7 +1024,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+        emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31);

+        if (irt_isnum(kt)) {

+  	emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1);

+ -	emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 0);

+ +	emit_dta(as, MIPSI_DSRA32, tmp1, LJ_SOFTFP ? key : tmp1, 0);

+  	emit_dta(as, MIPSI_SLL, tmp2, LJ_SOFTFP ? key : tmp1, 0);

+  #if !LJ_SOFTFP

+  	emit_tg(as, MIPSI_DMFC1, tmp1, key);

+ @@ -1123,7 +1187,7 @@ static MIPSIns asm_fxloadins(IRIns *ir)

+    case IRT_U8: return MIPSI_LBU;

+    case IRT_I16: return MIPSI_LH;

+    case IRT_U16: return MIPSI_LHU;

+ -  case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_LDC1;

+ +  case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1;

+    case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1;

+    default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW;

+    }

+ @@ -1134,7 +1198,7 @@ static MIPSIns asm_fxstoreins(IRIns *ir)

+    switch (irt_type(ir->t)) {

+    case IRT_I8: case IRT_U8: return MIPSI_SB;

+    case IRT_I16: case IRT_U16: return MIPSI_SH;

+ -  case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_SDC1;

+ +  case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1;

+    case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1;

+    default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW;

+    }

+ @@ -1199,7 +1263,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)

+  

+  static void asm_ahuvload(ASMState *as, IRIns *ir)

+  {

+ -  int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP);

+ +  int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP);

+    Reg dest = RID_NONE, type = RID_TMP, idx;

+    RegSet allow = RSET_GPR;

+    int32_t ofs = 0;

+ @@ -1212,7 +1276,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)

+      }

+    }

+    if (ra_used(ir)) {

+ -    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||

+ +    lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||

+  	       irt_isint(ir->t) || irt_isaddr(ir->t));

+      dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);

+      rset_clear(allow, dest);

+ @@ -1261,10 +1325,10 @@ static void asm_ahustore(ASMState *as, IRIns *ir)

+    int32_t ofs = 0;

+    if (ir->r == RID_SINK)

+      return;

+ -  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+ -    src = ra_alloc1(as, ir->op2, RSET_FPR);

+ +  if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {

+ +    src = ra_alloc1(as, ir->op2, LJ_SOFTFP ? RSET_GPR : RSET_FPR);

+      idx = asm_fuseahuref(as, ir->op1, &ofs, allow);

+ -    emit_hsi(as, MIPSI_SDC1, src, idx, ofs);

+ +    emit_hsi(as, LJ_SOFTFP ? MIPSI_SD : MIPSI_SDC1, src, idx, ofs);

+    } else {

+  #if LJ_32

+      if (!irt_ispri(ir->t)) {

+ @@ -1312,7 +1376,7 @@ static void asm_sload(ASMState *as, IRIns *ir)

+    IRType1 t = ir->t;

+  #if LJ_32

+    int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0);

+ -  int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP);

+ +  int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP);

+    if (hiop)

+      t.irt = IRT_NUM;

+  #else

+ @@ -1320,7 +1384,7 @@ static void asm_sload(ASMState *as, IRIns *ir)

+  #endif

+    lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */

+    lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));

+ -#if LJ_32 && LJ_SOFTFP

+ +#if LJ_SOFTFP32

+    lua_assert(!(ir->op2 & IRSLOAD_CONVERT));  /* Handled by LJ_SOFTFP SPLIT. */

+    if (hiop && ra_used(ir+1)) {

+      type = ra_dest(as, ir+1, allow);

+ @@ -1328,29 +1392,44 @@ static void asm_sload(ASMState *as, IRIns *ir)

+    }

+  #else

+    if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {

+ -    dest = ra_scratch(as, RSET_FPR);

+ +    dest = ra_scratch(as, LJ_SOFTFP ? allow : RSET_FPR);

+      asm_tointg(as, ir, dest);

+      t.irt = IRT_NUM;  /* Continue with a regular number type check. */

+    } else

+  #endif

+    if (ra_used(ir)) {

+ -    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||

+ +    lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||

+  	       irt_isint(ir->t) || irt_isaddr(ir->t));

+      dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);

+      rset_clear(allow, dest);

+      base = ra_alloc1(as, REF_BASE, allow);

+      rset_clear(allow, base);

+ -    if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) {

+ +    if (!LJ_SOFTFP32 && (ir->op2 & IRSLOAD_CONVERT)) {

+        if (irt_isint(t)) {

+ -	Reg tmp = ra_scratch(as, RSET_FPR);

+ +	Reg tmp = ra_scratch(as, LJ_SOFTFP ? RSET_GPR : RSET_FPR);

+ +#if LJ_SOFTFP

+ +	ra_evictset(as, rset_exclude(RSET_SCRATCH, dest));

+ +	ra_destreg(as, ir, RID_RET);

+ +	emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_d2i].func, 0);

+ +	if (tmp != REGARG_FIRSTGPR)

+ +	  emit_move(as, REGARG_FIRSTGPR, tmp);

+ +#else

+  	emit_tg(as, MIPSI_MFC1, dest, tmp);

+  	emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp);

+ +#endif

+  	dest = tmp;

+  	t.irt = IRT_NUM;  /* Check for original type. */

+        } else {

+  	Reg tmp = ra_scratch(as, RSET_GPR);

+ +#if LJ_SOFTFP

+ +	ra_evictset(as, rset_exclude(RSET_SCRATCH, dest));

+ +	ra_destreg(as, ir, RID_RET);

+ +	emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_i2d].func, 0);

+ +	emit_dta(as, MIPSI_SLL, REGARG_FIRSTGPR, tmp, 0);

+ +#else

+  	emit_fg(as, MIPSI_CVT_D_W, dest, dest);

+  	emit_tg(as, MIPSI_MTC1, tmp, dest);

+ +#endif

+  	dest = tmp;

+  	t.irt = IRT_INT;  /* Check for original type. */

+        }

+ @@ -1399,7 +1478,7 @@ dotypecheck:

+        if (irt_isnum(t)) {

+  	asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);

+  	emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM);

+ -	if (ra_hasreg(dest))

+ +	if (!LJ_SOFTFP && ra_hasreg(dest))

+  	  emit_hsi(as, MIPSI_LDC1, dest, base, ofs);

+        } else {

+  	asm_guard(as, MIPSI_BNE, RID_TMP,

+ @@ -1409,7 +1488,7 @@ dotypecheck:

+      }

+      emit_tsi(as, MIPSI_LD, type, base, ofs);

+    } else if (ra_hasreg(dest)) {

+ -    if (irt_isnum(t))

+ +    if (!LJ_SOFTFP && irt_isnum(t))

+        emit_hsi(as, MIPSI_LDC1, dest, base, ofs);

+      else

+        emit_tsi(as, irt_isint(t) ? MIPSI_LW : MIPSI_LD, dest, base,

+ @@ -1548,26 +1627,40 @@ static void asm_fpunary(ASMState *as, IRIns *ir, MIPSIns mi)

+    Reg left = ra_hintalloc(as, ir->op1, dest, RSET_FPR);

+    emit_fg(as, mi, dest, left);

+  }

+ +#endif

+  

+ +#if !LJ_SOFTFP32

+  static void asm_fpmath(ASMState *as, IRIns *ir)

+  {

+    if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))

+      return;

+ +#if !LJ_SOFTFP

+    if (ir->op2 <= IRFPM_TRUNC)

+      asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);

+    else if (ir->op2 == IRFPM_SQRT)

+      asm_fpunary(as, ir, MIPSI_SQRT_D);

+    else

+ +#endif

+      asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);

+  }

+  #endif

+  

+ +#if !LJ_SOFTFP

+ +#define asm_fpadd(as, ir)	asm_fparith(as, ir, MIPSI_ADD_D)

+ +#define asm_fpsub(as, ir)	asm_fparith(as, ir, MIPSI_SUB_D)

+ +#define asm_fpmul(as, ir)	asm_fparith(as, ir, MIPSI_MUL_D)

+ +#elif LJ_64  /* && LJ_SOFTFP */

+ +#define asm_fpadd(as, ir)	asm_callid(as, ir, IRCALL_softfp_add)

+ +#define asm_fpsub(as, ir)	asm_callid(as, ir, IRCALL_softfp_sub)

+ +#define asm_fpmul(as, ir)	asm_callid(as, ir, IRCALL_softfp_mul)

+ +#endif

+ +

+  static void asm_add(ASMState *as, IRIns *ir)

+  {

+    IRType1 t = ir->t;

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+    if (irt_isnum(t)) {

+ -    asm_fparith(as, ir, MIPSI_ADD_D);

+ +    asm_fpadd(as, ir);

+    } else

+  #endif

+    {

+ @@ -1589,9 +1682,9 @@ static void asm_add(ASMState *as, IRIns *ir)

+  

+  static void asm_sub(ASMState *as, IRIns *ir)

+  {

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+    if (irt_isnum(ir->t)) {

+ -    asm_fparith(as, ir, MIPSI_SUB_D);

+ +    asm_fpsub(as, ir);

+    } else

+  #endif

+    {

+ @@ -1605,9 +1698,9 @@ static void asm_sub(ASMState *as, IRIns *ir)

+  

+  static void asm_mul(ASMState *as, IRIns *ir)

+  {

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+    if (irt_isnum(ir->t)) {

+ -    asm_fparith(as, ir, MIPSI_MUL_D);

+ +    asm_fpmul(as, ir);

+    } else

+  #endif

+    {

+ @@ -1634,7 +1727,7 @@ static void asm_mod(ASMState *as, IRIns *ir)

+      asm_callid(as, ir, IRCALL_lj_vm_modi);

+  }

+  

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+  static void asm_pow(ASMState *as, IRIns *ir)

+  {

+  #if LJ_64 && LJ_HASFFI

+ @@ -1654,7 +1747,11 @@ static void asm_div(ASMState *as, IRIns *ir)

+  					  IRCALL_lj_carith_divu64);

+    else

+  #endif

+ +#if !LJ_SOFTFP

+      asm_fparith(as, ir, MIPSI_DIV_D);

+ +#else

+ +  asm_callid(as, ir, IRCALL_softfp_div);

+ +#endif

+  }

+  #endif

+  

+ @@ -1664,6 +1761,13 @@ static void asm_neg(ASMState *as, IRIns *ir)

+    if (irt_isnum(ir->t)) {

+      asm_fpunary(as, ir, MIPSI_NEG_D);

+    } else

+ +#elif LJ_64  /* && LJ_SOFTFP */

+ +  if (irt_isnum(ir->t)) {

+ +    Reg dest = ra_dest(as, ir, RSET_GPR);

+ +    Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);

+ +    emit_dst(as, MIPSI_XOR, dest, left,

+ +	    ra_allock(as, 0x8000000000000000ll, rset_exclude(RSET_GPR, dest)));

+ +  } else

+  #endif

+    {

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+ @@ -1673,7 +1777,17 @@ static void asm_neg(ASMState *as, IRIns *ir)

+    }

+  }

+  

+ +#if !LJ_SOFTFP

+  #define asm_abs(as, ir)		asm_fpunary(as, ir, MIPSI_ABS_D)

+ +#elif LJ_64   /* && LJ_SOFTFP */

+ +static void asm_abs(ASMState *as, IRIns *ir)

+ +{

+ +  Reg dest = ra_dest(as, ir, RSET_GPR);

+ +  Reg left = ra_alloc1(as, ir->op1, RSET_GPR);

+ +  emit_tsml(as, MIPSI_DEXTM, dest, left, 30, 0);

+ +}

+ +#endif

+ +

+  #define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)

+  #define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)

+  

+ @@ -1918,15 +2032,21 @@ static void asm_bror(ASMState *as, IRIns *ir)

+    }

+  }

+  

+ -#if LJ_32 && LJ_SOFTFP

+ +#if LJ_SOFTFP

+  static void asm_sfpmin_max(ASMState *as, IRIns *ir)

+  {

+    CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax];

+ +#if LJ_64

+ +  IRRef args[2];

+ +  args[0] = ir->op1;

+ +  args[1] = ir->op2;

+ +#else

+    IRRef args[4];

+    args[0^LJ_BE] = ir->op1;

+    args[1^LJ_BE] = (ir+1)->op1;

+    args[2^LJ_BE] = ir->op2;

+    args[3^LJ_BE] = (ir+1)->op2;

+ +#endif

+    asm_setupresult(as, ir, &ci);

+    emit_call(as, (void *)ci.func, 0);

+    ci.func = NULL;

+ @@ -1936,7 +2056,10 @@ static void asm_sfpmin_max(ASMState *as, IRIns *ir)

+  

+  static void asm_min_max(ASMState *as, IRIns *ir, int ismax)

+  {

+ -  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {

+ +#if LJ_SOFTFP

+ +    asm_sfpmin_max(as, ir);

+ +#else

+      Reg dest = ra_dest(as, ir, RSET_FPR);

+      Reg right, left = ra_alloc2(as, ir, RSET_FPR);

+      right = (left >> 8); left &= 255;

+ @@ -1947,6 +2070,7 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)

+        if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);

+      }

+      emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);

+ +#endif

+    } else {

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+      Reg right, left = ra_alloc2(as, ir, RSET_GPR);

+ @@ -1967,18 +2091,24 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)

+  

+  /* -- Comparisons --------------------------------------------------------- */

+  

+ -#if LJ_32 && LJ_SOFTFP

+ +#if LJ_SOFTFP

+  /* SFP comparisons. */

+  static void asm_sfpcomp(ASMState *as, IRIns *ir)

+  {

+    const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];

+    RegSet drop = RSET_SCRATCH;

+    Reg r;

+ +#if LJ_64

+ +  IRRef args[2];

+ +  args[0] = ir->op1;

+ +  args[1] = ir->op2;

+ +#else

+    IRRef args[4];

+    args[LJ_LE ? 0 : 1] = ir->op1; args[LJ_LE ? 1 : 0] = (ir+1)->op1;

+    args[LJ_LE ? 2 : 3] = ir->op2; args[LJ_LE ? 3 : 2] = (ir+1)->op2;

+ +#endif

+  

+ -  for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) {

+ +  for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+(LJ_64?1:3); r++) {

+      if (!rset_test(as->freeset, r) &&

+  	regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR])

+        rset_clear(drop, r);

+ @@ -2032,11 +2162,15 @@ static void asm_comp(ASMState *as, IRIns *ir)

+  {

+    /* ORDER IR: LT GE LE GT  ULT UGE ULE UGT. */

+    IROp op = ir->o;

+ -  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {

+ +#if LJ_SOFTFP

+ +    asm_sfpcomp(as, ir);

+ +#else

+      Reg right, left = ra_alloc2(as, ir, RSET_FPR);

+      right = (left >> 8); left &= 255;

+      asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);

+      emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right);

+ +#endif

+    } else {

+      Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);

+      if (op == IR_ABC) op = IR_UGT;

+ @@ -2068,9 +2202,13 @@ static void asm_equal(ASMState *as, IRIns *ir)

+    Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ?

+  				       RSET_FPR : RSET_GPR);

+    right = (left >> 8); left &= 255;

+ -  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {

+ +#if LJ_SOFTFP

+ +    asm_sfpcomp(as, ir);

+ +#else

+      asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);

+      emit_fgh(as, MIPSI_C_EQ_D, 0, left, right);

+ +#endif

+    } else {

+      asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right);

+    }

+ @@ -2263,7 +2401,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)

+      if ((sn & SNAP_NORESTORE))

+        continue;

+      if (irt_isnum(ir->t)) {

+ -#if LJ_SOFTFP

+ +#if LJ_SOFTFP32

+        Reg tmp;

+        RegSet allow = rset_exclude(RSET_GPR, RID_BASE);

+        lua_assert(irref_isk(ref));  /* LJ_SOFTFP: must be a number constant. */

+ @@ -2272,6 +2410,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)

+        if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);

+        tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow);

+        emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?0:4));

+ +#elif LJ_SOFTFP  /* && LJ_64 */

+ +      Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));

+ +      emit_tsi(as, MIPSI_SD, src, RID_BASE, ofs);

+  #else

+        Reg src = ra_alloc1(as, ref, RSET_FPR);

+        emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs);

+ diff --git a/src/lj_crecord.c b/src/lj_crecord.c

+ index e32ae23..fd59e28 100644

+ --- a/src/lj_crecord.c

+ +++ b/src/lj_crecord.c

+ @@ -212,7 +212,7 @@ static void crec_copy_emit(jit_State *J, CRecMemList *ml, MSize mlp,

+      ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);

+      ml[i].trofs = trofs;

+      i++;

+ -    rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1;

+ +    rwin += (LJ_SOFTFP32 && ml[i].tp == IRT_NUM) ? 2 : 1;

+      if (rwin >= CREC_COPY_REGWIN || i >= mlp) {  /* Flush buffered stores. */

+        rwin = 0;

+        for ( ; j < i; j++) {

+ @@ -1130,7 +1130,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,

+  	else

+  	  tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);

+        }

+ -    } else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) {

+ +    } else if (LJ_SOFTFP32 && ctype_isfp(d->info) && d->size > 4) {

+        lj_needsplit(J);

+      }

+  #if LJ_TARGET_X86

+ diff --git a/src/lj_emit_mips.h b/src/lj_emit_mips.h

+ index 8a9ee24..bb6593a 100644

+ --- a/src/lj_emit_mips.h

+ +++ b/src/lj_emit_mips.h

+ @@ -12,6 +12,8 @@ static intptr_t get_k64val(IRIns *ir)

+      return (intptr_t)ir_kgc(ir);

+    } else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {

+      return (intptr_t)ir_kptr(ir);

+ +  } else if (LJ_SOFTFP && ir->o == IR_KNUM) {

+ +    return (intptr_t)ir_knum(ir)->u64;

+    } else {

+      lua_assert(ir->o == IR_KINT || ir->o == IR_KNULL);

+      return ir->i;  /* Sign-extended. */

+ diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c

+ index dfdee2d..849d7a2 100644

+ --- a/src/lj_ffrecord.c

+ +++ b/src/lj_ffrecord.c

+ @@ -1012,7 +1012,7 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd)

+      handle_num:

+        tra = lj_ir_tonum(J, tra);

+        tr = lj_ir_call(J, id, tr, trsf, tra);

+ -      if (LJ_SOFTFP) lj_needsplit(J);

+ +      if (LJ_SOFTFP32) lj_needsplit(J);

+        break;

+      case STRFMT_STR:

+        if (!tref_isstr(tra)) {

+ diff --git a/src/lj_ircall.h b/src/lj_ircall.h

+ index 973c36e..7312006 100644

+ --- a/src/lj_ircall.h

+ +++ b/src/lj_ircall.h

+ @@ -51,7 +51,7 @@ typedef struct CCallInfo {

+  #define CCI_XARGS(ci)		(((ci)->flags >> CCI_XARGS_SHIFT) & 3)

+  #define CCI_XA			(1u << CCI_XARGS_SHIFT)

+  

+ -#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)

+ +#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)

+  #define CCI_XNARGS(ci)		(CCI_NARGS((ci)) + CCI_XARGS((ci)))

+  #else

+  #define CCI_XNARGS(ci)		CCI_NARGS((ci))

+ @@ -78,13 +78,19 @@ typedef struct CCallInfo {

+  #define IRCALLCOND_SOFTFP_FFI(x)	NULL

+  #endif

+  

+ -#if LJ_SOFTFP && LJ_TARGET_MIPS32

+ +#if LJ_SOFTFP && LJ_TARGET_MIPS

+  #define IRCALLCOND_SOFTFP_MIPS(x)	x

+  #else

+  #define IRCALLCOND_SOFTFP_MIPS(x)	NULL

+  #endif

+  

+ -#define LJ_NEED_FP64	(LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS32)

+ +#if LJ_SOFTFP && LJ_TARGET_MIPS64

+ +#define IRCALLCOND_SOFTFP_MIPS64(x)	x

+ +#else

+ +#define IRCALLCOND_SOFTFP_MIPS64(x)	NULL

+ +#endif

+ +

+ +#define LJ_NEED_FP64	(LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS)

+  

+  #if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64)

+  #define IRCALLCOND_FP64_FFI(x)		x

+ @@ -112,6 +118,14 @@ typedef struct CCallInfo {

+  #define XA2_FP		0

+  #endif

+  

+ +#if LJ_SOFTFP32

+ +#define XA_FP32		CCI_XA

+ +#define XA2_FP32	(CCI_XA+CCI_XA)

+ +#else

+ +#define XA_FP32		0

+ +#define XA2_FP32	0

+ +#endif

+ +

+  #if LJ_32

+  #define XA_64		CCI_XA

+  #define XA2_64		(CCI_XA+CCI_XA)

+ @@ -181,20 +195,21 @@ typedef struct CCallInfo {

+    _(ANY,	pow,			2,   N, NUM, XA2_FP) \

+    _(ANY,	atan2,			2,   N, NUM, XA2_FP) \

+    _(ANY,	ldexp,			2,   N, NUM, XA_FP) \

+ -  _(SOFTFP,	lj_vm_tobit,		2,   N, INT, 0) \

+ -  _(SOFTFP,	softfp_add,		4,   N, NUM, 0) \

+ -  _(SOFTFP,	softfp_sub,		4,   N, NUM, 0) \

+ -  _(SOFTFP,	softfp_mul,		4,   N, NUM, 0) \

+ -  _(SOFTFP,	softfp_div,		4,   N, NUM, 0) \

+ -  _(SOFTFP,	softfp_cmp,		4,   N, NIL, 0) \

+ +  _(SOFTFP,	lj_vm_tobit,		1,   N, INT, XA_FP32) \

+ +  _(SOFTFP,	softfp_add,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP,	softfp_sub,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP,	softfp_mul,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP,	softfp_div,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP,	softfp_cmp,		2,   N, NIL, XA2_FP32) \

+    _(SOFTFP,	softfp_i2d,		1,   N, NUM, 0) \

+ -  _(SOFTFP,	softfp_d2i,		2,   N, INT, 0) \

+ -  _(SOFTFP_MIPS, lj_vm_sfmin,		4,   N, NUM, 0) \

+ -  _(SOFTFP_MIPS, lj_vm_sfmax,		4,   N, NUM, 0) \

+ +  _(SOFTFP,	softfp_d2i,		1,   N, INT, XA_FP32) \

+ +  _(SOFTFP_MIPS, lj_vm_sfmin,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP_MIPS, lj_vm_sfmax,		2,   N, NUM, XA2_FP32) \

+ +  _(SOFTFP_MIPS64, lj_vm_tointg,	1,   N, INT, 0) \

+    _(SOFTFP_FFI,	softfp_ui2d,		1,   N, NUM, 0) \

+    _(SOFTFP_FFI,	softfp_f2d,		1,   N, NUM, 0) \

+ -  _(SOFTFP_FFI,	softfp_d2ui,		2,   N, INT, 0) \

+ -  _(SOFTFP_FFI,	softfp_d2f,		2,   N, FLOAT, 0) \

+ +  _(SOFTFP_FFI,	softfp_d2ui,		1,   N, INT, XA_FP32) \

+ +  _(SOFTFP_FFI,	softfp_d2f,		1,   N, FLOAT, XA_FP32) \

+    _(SOFTFP_FFI,	softfp_i2f,		1,   N, FLOAT, 0) \

+    _(SOFTFP_FFI,	softfp_ui2f,		1,   N, FLOAT, 0) \

+    _(SOFTFP_FFI,	softfp_f2i,		1,   N, INT, 0) \

+ diff --git a/src/lj_iropt.h b/src/lj_iropt.h

+ index 73aef0e..a59ba3f 100644

+ --- a/src/lj_iropt.h

+ +++ b/src/lj_iropt.h

+ @@ -150,7 +150,7 @@ LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase);

+  /* Optimization passes. */

+  LJ_FUNC void lj_opt_dce(jit_State *J);

+  LJ_FUNC int lj_opt_loop(jit_State *J);

+ -#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)

+ +#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)

+  LJ_FUNC void lj_opt_split(jit_State *J);

+  #else

+  #define lj_opt_split(J)		UNUSED(J)

+ diff --git a/src/lj_jit.h b/src/lj_jit.h

+ index 2fa8efc..f37e792 100644

+ --- a/src/lj_jit.h

+ +++ b/src/lj_jit.h

+ @@ -374,7 +374,7 @@ enum {

+    ((TValue *)(((intptr_t)&J->ksimd[2*(n)] + 15) & ~(intptr_t)15))

+  

+  /* Set/reset flag to activate the SPLIT pass for the current trace. */

+ -#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)

+ +#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)

+  #define lj_needsplit(J)		(J->needsplit = 1)

+  #define lj_resetsplit(J)	(J->needsplit = 0)

+  #else

+ @@ -437,7 +437,7 @@ typedef struct jit_State {

+    MSize sizesnapmap;	/* Size of temp. snapshot map buffer. */

+  

+    PostProc postproc;	/* Required post-processing after execution. */

+ -#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)

+ +#if LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)

+    uint8_t needsplit;	/* Need SPLIT pass. */

+  #endif

+    uint8_t retryrec;	/* Retry recording. */

+ diff --git a/src/lj_obj.h b/src/lj_obj.h

+ index 52372c3..c7e4742 100644

+ --- a/src/lj_obj.h

+ +++ b/src/lj_obj.h

+ @@ -924,6 +924,9 @@ static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2)

+  

+  #if LJ_SOFTFP

+  LJ_ASMF int32_t lj_vm_tobit(double x);

+ +#if LJ_TARGET_MIPS64

+ +LJ_ASMF int32_t lj_vm_tointg(double x);

+ +#endif

+  #endif

+  

+  static LJ_AINLINE int32_t lj_num2bit(lua_Number n)

+ diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c

+ index fc93520..79ac3cc 100644

+ --- a/src/lj_opt_split.c

+ +++ b/src/lj_opt_split.c

+ @@ -8,7 +8,7 @@

+  

+  #include "lj_obj.h"

+  

+ -#if LJ_HASJIT && (LJ_SOFTFP || (LJ_32 && LJ_HASFFI))

+ +#if LJ_HASJIT && (LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI))

+  

+  #include "lj_err.h"

+  #include "lj_buf.h"

+ diff --git a/src/lj_snap.c b/src/lj_snap.c

+ index bb063c2..44fa379 100644

+ --- a/src/lj_snap.c

+ +++ b/src/lj_snap.c

+ @@ -93,7 +93,7 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots)

+  	    (ir->op2 & (IRSLOAD_READONLY|IRSLOAD_PARENT)) != IRSLOAD_PARENT)

+  	  sn |= SNAP_NORESTORE;

+        }

+ -      if (LJ_SOFTFP && irt_isnum(ir->t))

+ +      if (LJ_SOFTFP32 && irt_isnum(ir->t))

+  	sn |= SNAP_SOFTFPNUM;

+        map[n++] = sn;

+      }

+ @@ -374,7 +374,7 @@ IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir)

+  	  break;

+  	}

+        }

+ -    } else if (LJ_SOFTFP && ir->o == IR_HIOP) {

+ +    } else if (LJ_SOFTFP32 && ir->o == IR_HIOP) {

+        ref++;

+      } else if (ir->o == IR_PVAL) {

+        ref = ir->op1 + REF_BIAS;

+ @@ -486,7 +486,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T)

+      } else {

+        IRType t = irt_type(ir->t);

+        uint32_t mode = IRSLOAD_INHERIT|IRSLOAD_PARENT;

+ -      if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;

+ +      if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM)) t = IRT_NUM;

+        if (ir->o == IR_SLOAD) mode |= (ir->op2 & IRSLOAD_READONLY);

+        tr = emitir_raw(IRT(IR_SLOAD, t), s, mode);

+      }

+ @@ -520,7 +520,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T)

+  	    if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) {

+  	      if (snap_pref(J, T, map, nent, seen, irs->op2) == 0)

+  		snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1);

+ -	      else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) &&

+ +	      else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) &&

+  		       irs+1 < irlast && (irs+1)->o == IR_HIOP)

+  		snap_pref(J, T, map, nent, seen, (irs+1)->op2);

+  	    }

+ @@ -579,10 +579,10 @@ void lj_snap_replay(jit_State *J, GCtrace *T)

+  		lua_assert(irc->o == IR_CONV && irc->op2 == IRCONV_NUM_INT);

+  		val = snap_pref(J, T, map, nent, seen, irc->op1);

+  		val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);

+ -	      } else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) &&

+ +	      } else if ((LJ_SOFTFP32 || (LJ_32 && LJ_HASFFI)) &&

+  			 irs+1 < irlast && (irs+1)->o == IR_HIOP) {

+  		IRType t = IRT_I64;

+ -		if (LJ_SOFTFP && irt_type((irs+1)->t) == IRT_SOFTFP)

+ +		if (LJ_SOFTFP32 && irt_type((irs+1)->t) == IRT_SOFTFP)

+  		  t = IRT_NUM;

+  		lj_needsplit(J);

+  		if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) {

+ @@ -635,7 +635,7 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex,

+      int32_t *sps = &ex->spill[regsp_spill(rs)];

+      if (irt_isinteger(t)) {

+        setintV(o, *sps);

+ -#if !LJ_SOFTFP

+ +#if !LJ_SOFTFP32

+      } else if (irt_isnum(t)) {

+        o->u64 = *(uint64_t *)sps;

+  #endif

+ @@ -660,6 +660,9 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex,

+  #if !LJ_SOFTFP

+      } else if (irt_isnum(t)) {

+        setnumV(o, ex->fpr[r-RID_MIN_FPR]);

+ +#elif LJ_64  /* && LJ_SOFTFP */

+ +    } else if (irt_isnum(t)) {

+ +      o->u64 = ex->gpr[r-RID_MIN_GPR];

+  #endif

+  #if LJ_64 && !LJ_GC64

+      } else if (irt_is64(t)) {

+ @@ -813,7 +816,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,

+  	  val = lj_tab_set(J->L, t, &tmp);

+  	  /* NOBARRIER: The table is new (marked white). */

+  	  snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, val);

+ -	  if (LJ_SOFTFP && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) {

+ +	  if (LJ_SOFTFP32 && irs+1 < T->ir + T->nins && (irs+1)->o == IR_HIOP) {

+  	    snap_restoreval(J, T, ex, snapno, rfilt, (irs+1)->op2, &tmp);

+  	    val->u32.hi = tmp.u32.lo;

+  	  }

+ @@ -874,7 +877,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)

+  	continue;

+        }

+        snap_restoreval(J, T, ex, snapno, rfilt, ref, o);

+ -      if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && tvisint(o)) {

+ +      if (LJ_SOFTFP32 && (sn & SNAP_SOFTFPNUM) && tvisint(o)) {

+  	TValue tmp;

+  	snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp);

+  	o->u32.hi = tmp.u32.lo;

+ diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc

+ index c06270a..75b38de 100644

+ --- a/src/vm_mips64.dasc

+ +++ b/src/vm_mips64.dasc

+ @@ -1980,6 +1980,38 @@ static void build_subroutines(BuildCtx *ctx)

+    |1:

+    |  jr ra

+    |.  move CRET1, r0

+ +  |

+ +  |// FP number to int conversion with a check for soft-float.

+ +  |// Modifies CARG1, CRET1, CRET2, TMP0, AT.

+ +  |->vm_tointg:

+ +  |.if JIT

+ +  |  dsll CRET2, CARG1, 1

+ +  |  beqz CRET2, >2

+ +  |.  li TMP0, 1076

+ +  |  dsrl AT, CRET2, 53

+ +  |  dsubu TMP0, TMP0, AT

+ +  |  sltiu AT, TMP0, 54

+ +  |  beqz AT, >1

+ +  |.  dextm CRET2, CRET2, 0, 20

+ +  |  dinsu CRET2, AT, 21, 21

+ +  |  slt AT, CARG1, r0

+ +  |  dsrlv CRET1, CRET2, TMP0

+ +  |  dsubu CARG1, r0, CRET1

+ +  |  movn CRET1, CARG1, AT

+ +  |  li CARG1, 64

+ +  |  subu TMP0, CARG1, TMP0

+ +  |  dsllv CRET2, CRET2, TMP0	// Integer check.

+ +  |  sextw AT, CRET1

+ +  |  xor AT, CRET1, AT		// Range check.

+ +  |  jr ra

+ +  |.  movz CRET2, AT, CRET2

+ +  |1:

+ +  |  jr ra

+ +  |.  li CRET2, 1

+ +  |2:

+ +  |  jr ra

+ +  |.  move CRET1, r0

+ +  |.endif

+    |.endif

+    |

+    |.macro .ffunc_bit, name

+ @@ -2665,6 +2697,23 @@ static void build_subroutines(BuildCtx *ctx)

+    |.  li CRET1, 0

+    |.endif

+    |

+ +  |.macro sfmin_max, name, intins

+ +  |->vm_sf .. name:

+ +  |.if JIT and not FPU

+ +  |  move TMP2, ra

+ +  |  bal ->vm_sfcmpolt

+ +  |.  nop

+ +  |  move ra, TMP2

+ +  |  move TMP0, CRET1

+ +  |  move CRET1, CARG1

+ +  |  jr ra

+ +  |.  intins CRET1, CARG2, TMP0

+ +  |.endif

+ +  |.endmacro

+ +  |

+ +  |  sfmin_max min, movz

+ +  |  sfmin_max max, movn

+ +  |

+    |//-----------------------------------------------------------------------

+    |//-- Miscellaneous functions --------------------------------------------

+    |//-----------------------------------------------------------------------

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From b0ecc6dd65a0b40e1868f20719c4f7c4880dc32d Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 8 Jun 2017 00:15:15 +0200

+ Subject: [PATCH 06/72] FreeBSD/x64: Avoid changing resource limits, if not

+  needed.

+ 

+ ---

+  src/lj_alloc.c | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_alloc.c b/src/lj_alloc.c

+ index 95d15d0..9fc761c 100644

+ --- a/src/lj_alloc.c

+ +++ b/src/lj_alloc.c

+ @@ -343,7 +343,7 @@ static void *CALL_MMAP(size_t size)

+  }

+  #endif

+  

+ -#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4

+ +#if LJ_64 && !LJ_GC64 && ((defined(__FreeBSD__) && __FreeBSD__ < 10) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4

+  

+  #include <sys/resource.h>

+  

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,28 @@ 

+ From 6a71e71c1430e5a8f794a52cb2da66e2693db796 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 11 Jun 2017 10:02:08 +0200

+ Subject: [PATCH 07/72] Remove unused define.

+ MIME-Version: 1.0

+ Content-Type: text/plain; charset=UTF-8

+ Content-Transfer-Encoding: 8bit

+ 

+ Suggested by 罗泽轩.

+ ---

+  src/lj_def.h | 1 -

+  1 file changed, 1 deletion(-)

+ 

+ diff --git a/src/lj_def.h b/src/lj_def.h

+ index 2d8fff6..e67bb24 100644

+ --- a/src/lj_def.h

+ +++ b/src/lj_def.h

+ @@ -80,7 +80,6 @@ typedef unsigned int uintptr_t;

+  #define LJ_MIN_SBUF	32		/* Min. string buffer length. */

+  #define LJ_MIN_VECSZ	8		/* Min. size for growable vectors. */

+  #define LJ_MIN_IRSZ	32		/* Min. size for growable IR. */

+ -#define LJ_MIN_K64SZ	16		/* Min. size for chained K64Array. */

+  

+  /* JIT compiler limits. */

+  #define LJ_MAX_JSLOTS	250		/* Max. # of stack slots for a trace. */

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,33 @@ 

+ From 82151a4514e6538086f3f5e01cb8d4b22287b14f Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 12 Jun 2017 09:24:00 +0200

+ Subject: [PATCH 08/72] Modify fix for warning from 'ar'.

+ 

+ ---

+  src/Makefile | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/Makefile b/src/Makefile

+ index f7f81a4..24e8c0e 100644

+ --- a/src/Makefile

+ +++ b/src/Makefile

+ @@ -208,7 +208,7 @@ TARGET_CC= $(STATIC_CC)

+  TARGET_STCC= $(STATIC_CC)

+  TARGET_DYNCC= $(DYNAMIC_CC)

+  TARGET_LD= $(CROSS)$(CC)

+ -TARGET_AR= $(CROSS)ar rcus 2>/dev/null

+ +TARGET_AR= $(CROSS)ar rcus

+  TARGET_STRIP= $(CROSS)strip

+  

+  TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)

+ @@ -293,6 +293,7 @@ ifeq (Windows,$(TARGET_SYS))

+    TARGET_XSHLDFLAGS= -shared

+    TARGET_DYNXLDOPTS=

+  else

+ +  TARGET_AR+= 2>/dev/null

+  ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-stack-protector 2>/dev/null || echo 1))

+    TARGET_XCFLAGS+= -fno-stack-protector

+  endif

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,47 @@ 

+ From 7e662e4f87134f1e84f7bea80933e033c5bf53a3 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 26 Jul 2017 09:52:53 +0200

+ Subject: [PATCH 09/72] x64/LJ_GC64: Fix emit_rma().

+ 

+ ---

+  src/lj_emit_x86.h | 24 +++++++++++++++++++++---

+  1 file changed, 21 insertions(+), 3 deletions(-)

+ 

+ diff --git a/src/lj_emit_x86.h b/src/lj_emit_x86.h

+ index 5207f9d..5b139bd 100644

+ --- a/src/lj_emit_x86.h

+ +++ b/src/lj_emit_x86.h

+ @@ -343,9 +343,27 @@ static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr)

+      emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr));

+    } else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) {

+      emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr));

+ -  } else if (!checki32((intptr_t)addr) && (xo == XO_MOV || xo == XO_MOVSD)) {

+ -    emit_rmro(as, xo, rr, rr, 0);

+ -    emit_loadu64(as, rr, (uintptr_t)addr);

+ +  } else if (!checki32((intptr_t)addr)) {

+ +    Reg ra = (rr & 15);

+ +    if (xo != XO_MOV) {

+ +      /* We can't allocate a register here. Use and restore DISPATCH. Ugly. */

+ +      uint64_t dispaddr = (uintptr_t)J2GG(as->J)->dispatch;

+ +      uint8_t i8 = xo == XO_GROUP3b ? *as->mcp++ : 0;

+ +      ra = RID_DISPATCH;

+ +      if (checku32(dispaddr)) {

+ +	emit_loadi(as, ra, (int32_t)dispaddr);

+ +      } else {  /* Full-size 64 bit load. */

+ +	MCode *p = as->mcp;

+ +	*(uint64_t *)(p-8) = dispaddr;

+ +	p[-9] = (MCode)(XI_MOVri+(ra&7));

+ +	p[-10] = 0x48 + ((ra>>3)&1);

+ +	p -= 10;

+ +	as->mcp = p;

+ +      }

+ +      if (xo == XO_GROUP3b) emit_i8(as, i8);

+ +    }

+ +    emit_rmro(as, xo, rr, ra, 0);

+ +    emit_loadu64(as, ra, (uintptr_t)addr);

+    } else

+  #endif

+    {

+ -- 

+ 2.20.1

+ 

The added file is too large to be shown here, see it at: 0010-PPC-Add-soft-float-support-to-interpreter.patch
@@ -0,0 +1,25 @@ 

+ From f3d75075ed91137699c6071abe49e2252e794a9c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Fri, 18 Aug 2017 12:52:14 +0200

+ Subject: [PATCH 11/72] Use https for freelists.org links.

+ 

+ ---

+  doc/ext_ffi_semantics.html | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html

+ index 899640c..ae3c037 100644

+ --- a/doc/ext_ffi_semantics.html

+ +++ b/doc/ext_ffi_semantics.html

+ @@ -844,7 +844,7 @@ place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead.

+  <p>

+  The main use for parameterized types are libraries implementing abstract

+  data types

+ -(<a href="http://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">&raquo;</span>&nbsp;example</a>),

+ +(<a href="https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8">example</a>),

+  similar to what can be achieved with C++ template metaprogramming.

+  Another use case are derived types of anonymous structs, which avoids

+  pollution of the global struct namespace.

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,25 @@ 

+ From 6b0824852677cc12570c20a3211fbfe0e4f0ce14 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 28 Aug 2017 10:43:37 +0200

+ Subject: [PATCH 12/72] x64/LJ_GC64: Fix fallback case of asm_fuseloadk64().

+ 

+ Contributed by Peter Cawley.

+ ---

+  src/lj_asm_x86.h | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h

+ index 3e189b1..55c02d2 100644

+ --- a/src/lj_asm_x86.h

+ +++ b/src/lj_asm_x86.h

+ @@ -387,6 +387,7 @@ static Reg asm_fuseloadk64(ASMState *as, IRIns *ir)

+        ir->i = (int32_t)(as->mctop - as->mcbot);

+        as->mcbot += 8;

+        as->mclim = as->mcbot + MCLIM_REDZONE;

+ +      lj_mcode_commitbot(as->J, as->mcbot);

+      }

+      as->mrm.ofs = (int32_t)mcpofs(as, as->mctop - ir->i);

+      as->mrm.base = RID_RIP;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,751 @@ 

+ From 71b7bc88341945f13f3951e2bb5fd247b639ff7a Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 3 Sep 2017 23:20:53 +0200

+ Subject: [PATCH 13/72] PPC: Add soft-float support to JIT compiler backend.

+ 

+ Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.

+ Sponsored by Cisco Systems, Inc.

+ ---

+  src/lj_arch.h    |   1 -

+  src/lj_asm_ppc.h | 321 ++++++++++++++++++++++++++++++++++++++++-------

+  2 files changed, 278 insertions(+), 44 deletions(-)

+ 

+ diff --git a/src/lj_arch.h b/src/lj_arch.h

+ index 0145a7c..5962f3a 100644

+ --- a/src/lj_arch.h

+ +++ b/src/lj_arch.h

+ @@ -273,7 +273,6 @@

+  #endif

+  

+  #if LJ_ABI_SOFTFP

+ -#define LJ_ARCH_NOJIT		1  /* NYI */

+  #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL

+  #else

+  #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL_SINGLE

+ diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h

+ index 6daa861..1955429 100644

+ --- a/src/lj_asm_ppc.h

+ +++ b/src/lj_asm_ppc.h

+ @@ -226,6 +226,7 @@ static void asm_fusexrefx(ASMState *as, PPCIns pi, Reg rt, IRRef ref,

+    emit_tab(as, pi, rt, left, right);

+  }

+  

+ +#if !LJ_SOFTFP

+  /* Fuse to multiply-add/sub instruction. */

+  static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)

+  {

+ @@ -245,6 +246,7 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)

+    }

+    return 0;

+  }

+ +#endif

+  

+  /* -- Calls --------------------------------------------------------------- */

+  

+ @@ -253,13 +255,17 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+  {

+    uint32_t n, nargs = CCI_XNARGS(ci);

+    int32_t ofs = 8;

+ -  Reg gpr = REGARG_FIRSTGPR, fpr = REGARG_FIRSTFPR;

+ +  Reg gpr = REGARG_FIRSTGPR;

+ +#if !LJ_SOFTFP

+ +  Reg fpr = REGARG_FIRSTFPR;

+ +#endif

+    if ((void *)ci->func)

+      emit_call(as, (void *)ci->func);

+    for (n = 0; n < nargs; n++) {  /* Setup args. */

+      IRRef ref = args[n];

+      if (ref) {

+        IRIns *ir = IR(ref);

+ +#if !LJ_SOFTFP

+        if (irt_isfp(ir->t)) {

+  	if (fpr <= REGARG_LASTFPR) {

+  	  lua_assert(rset_test(as->freeset, fpr));  /* Already evicted. */

+ @@ -271,7 +277,9 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+  	  emit_spstore(as, ir, r, ofs);

+  	  ofs += irt_isnum(ir->t) ? 8 : 4;

+  	}

+ -      } else {

+ +      } else

+ +#endif

+ +      {

+  	if (gpr <= REGARG_LASTGPR) {

+  	  lua_assert(rset_test(as->freeset, gpr));  /* Already evicted. */

+  	  ra_leftov(as, gpr, ref);

+ @@ -290,8 +298,10 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)

+      }

+      checkmclim(as);

+    }

+ +#if !LJ_SOFTFP

+    if ((ci->flags & CCI_VARARG))  /* Vararg calls need to know about FPR use. */

+      emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6);

+ +#endif

+  }

+  

+  /* Setup result reg/sp for call. Evict scratch regs. */

+ @@ -299,8 +309,10 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)

+  {

+    RegSet drop = RSET_SCRATCH;

+    int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));

+ +#if !LJ_SOFTFP

+    if ((ci->flags & CCI_NOFPRCLOBBER))

+      drop &= ~RSET_FPR;

+ +#endif

+    if (ra_hasreg(ir->r))

+      rset_clear(drop, ir->r);  /* Dest reg handled below. */

+    if (hiop && ra_hasreg((ir+1)->r))

+ @@ -308,7 +320,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)

+    ra_evictset(as, drop);  /* Evictions must be performed first. */

+    if (ra_used(ir)) {

+      lua_assert(!irt_ispri(ir->t));

+ -    if (irt_isfp(ir->t)) {

+ +    if (!LJ_SOFTFP && irt_isfp(ir->t)) {

+        if ((ci->flags & CCI_CASTU64)) {

+  	/* Use spill slot or temp slots. */

+  	int32_t ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;

+ @@ -377,6 +389,7 @@ static void asm_retf(ASMState *as, IRIns *ir)

+  

+  /* -- Type conversions ---------------------------------------------------- */

+  

+ +#if !LJ_SOFTFP

+  static void asm_tointg(ASMState *as, IRIns *ir, Reg left)

+  {

+    RegSet allow = RSET_FPR;

+ @@ -409,15 +422,23 @@ static void asm_tobit(ASMState *as, IRIns *ir)

+    emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);

+    emit_fab(as, PPCI_FADD, tmp, left, right);

+  }

+ +#endif

+  

+  static void asm_conv(ASMState *as, IRIns *ir)

+  {

+    IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);

+ +#if !LJ_SOFTFP

+    int stfp = (st == IRT_NUM || st == IRT_FLOAT);

+ +#endif

+    IRRef lref = ir->op1;

+ -  lua_assert(irt_type(ir->t) != st);

+    lua_assert(!(irt_isint64(ir->t) ||

+  	       (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */

+ +#if LJ_SOFTFP

+ +  /* FP conversions are handled by SPLIT. */

+ +  lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));

+ +  /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */

+ +#else

+ +  lua_assert(irt_type(ir->t) != st);

+    if (irt_isfp(ir->t)) {

+      Reg dest = ra_dest(as, ir, RSET_FPR);

+      if (stfp) {  /* FP to FP conversion. */

+ @@ -476,7 +497,9 @@ static void asm_conv(ASMState *as, IRIns *ir)

+  	emit_fb(as, PPCI_FCTIWZ, tmp, left);

+        }

+      }

+ -  } else {

+ +  } else

+ +#endif

+ +  {

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+      if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */

+        Reg left = ra_alloc1(as, ir->op1, RSET_GPR);

+ @@ -496,17 +519,41 @@ static void asm_strto(ASMState *as, IRIns *ir)

+  {

+    const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];

+    IRRef args[2];

+ -  int32_t ofs;

+ +  int32_t ofs = SPOFS_TMP;

+ +#if LJ_SOFTFP

+ +  ra_evictset(as, RSET_SCRATCH);

+ +  if (ra_used(ir)) {

+ +    if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&

+ +	(ir->s & 1) == LJ_BE && (ir->s ^ 1) == (ir+1)->s) {

+ +      int i;

+ +      for (i = 0; i < 2; i++) {

+ +	Reg r = (ir+i)->r;

+ +	if (ra_hasreg(r)) {

+ +	  ra_free(as, r);

+ +	  ra_modified(as, r);

+ +	  emit_spload(as, ir+i, r, sps_scale((ir+i)->s));

+ +	}

+ +      }

+ +      ofs = sps_scale(ir->s & ~1);

+ +    } else {

+ +      Reg rhi = ra_dest(as, ir+1, RSET_GPR);

+ +      Reg rlo = ra_dest(as, ir, rset_exclude(RSET_GPR, rhi));

+ +      emit_tai(as, PPCI_LWZ, rhi, RID_SP, ofs);

+ +      emit_tai(as, PPCI_LWZ, rlo, RID_SP, ofs+4);

+ +    }

+ +  }

+ +#else

+    RegSet drop = RSET_SCRATCH;

+    if (ra_hasreg(ir->r)) rset_set(drop, ir->r);  /* Spill dest reg (if any). */

+    ra_evictset(as, drop);

+ +  if (ir->s) ofs = sps_scale(ir->s);

+ +#endif

+    asm_guardcc(as, CC_EQ);

+    emit_ai(as, PPCI_CMPWI, RID_RET, 0);  /* Test return status. */

+    args[0] = ir->op1;      /* GCstr *str */

+    args[1] = ASMREF_TMP1;  /* TValue *n  */

+    asm_gencall(as, ci, args);

+    /* Store the result to the spill slot or temp slots. */

+ -  ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;

+    emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs);

+  }

+  

+ @@ -530,7 +577,10 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)

+        Reg src = ra_alloc1(as, ref, allow);

+        emit_setgl(as, src, tmptv.gcr);

+      }

+ -    type = ra_allock(as, irt_toitype(ir->t), allow);

+ +    if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)

+ +      type = ra_alloc1(as, ref+1, allow);

+ +    else

+ +      type = ra_allock(as, irt_toitype(ir->t), allow);

+      emit_setgl(as, type, tmptv.it);

+    }

+  }

+ @@ -574,11 +624,27 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+    Reg tisnum = RID_NONE, tmpnum = RID_NONE;

+    IRRef refkey = ir->op2;

+    IRIns *irkey = IR(refkey);

+ +  int isk = irref_isk(refkey);

+    IRType1 kt = irkey->t;

+    uint32_t khash;

+    MCLabel l_end, l_loop, l_next;

+  

+    rset_clear(allow, tab);

+ +#if LJ_SOFTFP

+ +  if (!isk) {

+ +    key = ra_alloc1(as, refkey, allow);

+ +    rset_clear(allow, key);

+ +    if (irkey[1].o == IR_HIOP) {

+ +      if (ra_hasreg((irkey+1)->r)) {

+ +	tmpnum = (irkey+1)->r;

+ +	ra_noweak(as, tmpnum);

+ +      } else {

+ +	tmpnum = ra_allocref(as, refkey+1, allow);

+ +      }

+ +      rset_clear(allow, tmpnum);

+ +    }

+ +  }

+ +#else

+    if (irt_isnum(kt)) {

+      key = ra_alloc1(as, refkey, RSET_FPR);

+      tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));

+ @@ -588,6 +654,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+      key = ra_alloc1(as, refkey, allow);

+      rset_clear(allow, key);

+    }

+ +#endif

+    tmp2 = ra_scratch(as, allow);

+    rset_clear(allow, tmp2);

+  

+ @@ -610,7 +677,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+      asm_guardcc(as, CC_EQ);

+    else

+      emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);

+ -  if (irt_isnum(kt)) {

+ +  if (!LJ_SOFTFP && irt_isnum(kt)) {

+      emit_fab(as, PPCI_FCMPU, 0, tmpnum, key);

+      emit_condbranch(as, PPCI_BC, CC_GE, l_next);

+      emit_ab(as, PPCI_CMPLW, tmp1, tisnum);

+ @@ -620,7 +687,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+        emit_ab(as, PPCI_CMPW, tmp2, key);

+        emit_condbranch(as, PPCI_BC, CC_NE, l_next);

+      }

+ -    emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));

+ +    if (LJ_SOFTFP && ra_hasreg(tmpnum))

+ +      emit_ab(as, PPCI_CMPW, tmp1, tmpnum);

+ +    else

+ +      emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));

+      if (!irt_ispri(kt))

+        emit_tai(as, PPCI_LWZ, tmp2, dest, (int32_t)offsetof(Node, key.gcr));

+    }

+ @@ -629,19 +699,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+  	    (((char *)as->mcp-(char *)l_loop) & 0xffffu);

+  

+    /* Load main position relative to tab->node into dest. */

+ -  khash = irref_isk(refkey) ? ir_khash(irkey) : 1;

+ +  khash = isk ? ir_khash(irkey) : 1;

+    if (khash == 0) {

+      emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));

+    } else {

+      Reg tmphash = tmp1;

+ -    if (irref_isk(refkey))

+ +    if (isk)

+        tmphash = ra_allock(as, khash, allow);

+      emit_tab(as, PPCI_ADD, dest, dest, tmp1);

+      emit_tai(as, PPCI_MULLI, tmp1, tmp1, sizeof(Node));

+      emit_asb(as, PPCI_AND, tmp1, tmp2, tmphash);

+      emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));

+      emit_tai(as, PPCI_LWZ, tmp2, tab, (int32_t)offsetof(GCtab, hmask));

+ -    if (irref_isk(refkey)) {

+ +    if (isk) {

+        /* Nothing to do. */

+      } else if (irt_isstr(kt)) {

+        emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash));

+ @@ -651,13 +721,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+        emit_asb(as, PPCI_XOR, tmp1, tmp1, tmp2);

+        emit_rotlwi(as, tmp1, tmp1, (HASH_ROT2+HASH_ROT1)&31);

+        emit_tab(as, PPCI_SUBF, tmp2, dest, tmp2);

+ -      if (irt_isnum(kt)) {

+ +      if (LJ_SOFTFP ? (irkey[1].o == IR_HIOP) : irt_isnum(kt)) {

+ +#if LJ_SOFTFP

+ +	emit_asb(as, PPCI_XOR, tmp2, key, tmp1);

+ +	emit_rotlwi(as, dest, tmp1, HASH_ROT1);

+ +	emit_tab(as, PPCI_ADD, tmp1, tmpnum, tmpnum);

+ +#else

+  	int32_t ofs = ra_spill(as, irkey);

+  	emit_asb(as, PPCI_XOR, tmp2, tmp2, tmp1);

+  	emit_rotlwi(as, dest, tmp1, HASH_ROT1);

+  	emit_tab(as, PPCI_ADD, tmp1, tmp1, tmp1);

+  	emit_tai(as, PPCI_LWZ, tmp2, RID_SP, ofs+4);

+  	emit_tai(as, PPCI_LWZ, tmp1, RID_SP, ofs);

+ +#endif

+        } else {

+  	emit_asb(as, PPCI_XOR, tmp2, key, tmp1);

+  	emit_rotlwi(as, dest, tmp1, HASH_ROT1);

+ @@ -784,8 +860,8 @@ static PPCIns asm_fxloadins(IRIns *ir)

+    case IRT_U8: return PPCI_LBZ;

+    case IRT_I16: return PPCI_LHA;

+    case IRT_U16: return PPCI_LHZ;

+ -  case IRT_NUM: return PPCI_LFD;

+ -  case IRT_FLOAT: return PPCI_LFS;

+ +  case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_LFD;

+ +  case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_LFS;

+    default: return PPCI_LWZ;

+    }

+  }

+ @@ -795,8 +871,8 @@ static PPCIns asm_fxstoreins(IRIns *ir)

+    switch (irt_type(ir->t)) {

+    case IRT_I8: case IRT_U8: return PPCI_STB;

+    case IRT_I16: case IRT_U16: return PPCI_STH;

+ -  case IRT_NUM: return PPCI_STFD;

+ -  case IRT_FLOAT: return PPCI_STFS;

+ +  case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_STFD;

+ +  case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_STFS;

+    default: return PPCI_STW;

+    }

+  }

+ @@ -839,7 +915,8 @@ static void asm_fstore(ASMState *as, IRIns *ir)

+  

+  static void asm_xload(ASMState *as, IRIns *ir)

+  {

+ -  Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+ +  Reg dest = ra_dest(as, ir,

+ +    (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);

+    lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));

+    if (irt_isi8(ir->t))

+      emit_as(as, PPCI_EXTSB, dest, dest);

+ @@ -857,7 +934,8 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)

+      Reg src = ra_alloc1(as, irb->op1, RSET_GPR);

+      asm_fusexrefx(as, PPCI_STWBRX, src, ir->op1, rset_exclude(RSET_GPR, src));

+    } else {

+ -    Reg src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+ +    Reg src = ra_alloc1(as, ir->op2,

+ +      (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);

+      asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,

+  		 rset_exclude(RSET_GPR, src), ofs);

+    }

+ @@ -871,10 +949,19 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)

+    Reg dest = RID_NONE, type = RID_TMP, tmp = RID_TMP, idx;

+    RegSet allow = RSET_GPR;

+    int32_t ofs = AHUREF_LSX;

+ +  if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) {

+ +    t.irt = IRT_NUM;

+ +    if (ra_used(ir+1)) {

+ +      type = ra_dest(as, ir+1, allow);

+ +      rset_clear(allow, type);

+ +    }

+ +    ofs = 0;

+ +  }

+    if (ra_used(ir)) {

+ -    lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));

+ -    if (!irt_isnum(t)) ofs = 0;

+ -    dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);

+ +    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||

+ +	       irt_isint(ir->t) || irt_isaddr(ir->t));

+ +    if (LJ_SOFTFP || !irt_isnum(t)) ofs = 0;

+ +    dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);

+      rset_clear(allow, dest);

+    }

+    idx = asm_fuseahuref(as, ir->op1, &ofs, allow);

+ @@ -883,12 +970,13 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)

+      asm_guardcc(as, CC_GE);

+      emit_ab(as, PPCI_CMPLW, type, tisnum);

+      if (ra_hasreg(dest)) {

+ -      if (ofs == AHUREF_LSX) {

+ +      if (!LJ_SOFTFP && ofs == AHUREF_LSX) {

+  	tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR,

+  						       (idx&255)), (idx>>8)));

+  	emit_fab(as, PPCI_LFDX, dest, (idx&255), tmp);

+        } else {

+ -	emit_fai(as, PPCI_LFD, dest, idx, ofs);

+ +	emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest, idx,

+ +		 ofs+4*LJ_SOFTFP);

+        }

+      }

+    } else {

+ @@ -911,7 +999,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir)

+    int32_t ofs = AHUREF_LSX;

+    if (ir->r == RID_SINK)

+      return;

+ -  if (irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+      src = ra_alloc1(as, ir->op2, RSET_FPR);

+    } else {

+      if (!irt_ispri(ir->t)) {

+ @@ -919,11 +1007,14 @@ static void asm_ahustore(ASMState *as, IRIns *ir)

+        rset_clear(allow, src);

+        ofs = 0;

+      }

+ -    type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);

+ +    if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)

+ +      type = ra_alloc1(as, (ir+1)->op2, allow);

+ +    else

+ +      type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);

+      rset_clear(allow, type);

+    }

+    idx = asm_fuseahuref(as, ir->op1, &ofs, allow);

+ -  if (irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+      if (ofs == AHUREF_LSX) {

+        emit_fab(as, PPCI_STFDX, src, (idx&255), RID_TMP);

+        emit_slwi(as, RID_TMP, (idx>>8), 3);

+ @@ -948,21 +1039,33 @@ static void asm_sload(ASMState *as, IRIns *ir)

+    IRType1 t = ir->t;

+    Reg dest = RID_NONE, type = RID_NONE, base;

+    RegSet allow = RSET_GPR;

+ +  int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);

+ +  if (hiop)

+ +    t.irt = IRT_NUM;

+    lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */

+ -  lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));

+ +  lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));

+    lua_assert(LJ_DUALNUM ||

+  	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));

+ +#if LJ_SOFTFP

+ +  lua_assert(!(ir->op2 & IRSLOAD_CONVERT));  /* Handled by LJ_SOFTFP SPLIT. */

+ +  if (hiop && ra_used(ir+1)) {

+ +    type = ra_dest(as, ir+1, allow);

+ +    rset_clear(allow, type);

+ +  }

+ +#else

+    if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {

+      dest = ra_scratch(as, RSET_FPR);

+      asm_tointg(as, ir, dest);

+      t.irt = IRT_NUM;  /* Continue with a regular number type check. */

+ -  } else if (ra_used(ir)) {

+ +  } else

+ +#endif

+ +  if (ra_used(ir)) {

+      lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));

+ -    dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);

+ +    dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);

+      rset_clear(allow, dest);

+      base = ra_alloc1(as, REF_BASE, allow);

+      rset_clear(allow, base);

+ -    if ((ir->op2 & IRSLOAD_CONVERT)) {

+ +    if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) {

+        if (irt_isint(t)) {

+  	emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);

+  	dest = ra_scratch(as, RSET_FPR);

+ @@ -994,10 +1097,13 @@ dotypecheck:

+      if ((ir->op2 & IRSLOAD_TYPECHECK)) {

+        Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow);

+        asm_guardcc(as, CC_GE);

+ -      emit_ab(as, PPCI_CMPLW, RID_TMP, tisnum);

+ +#if !LJ_SOFTFP

+        type = RID_TMP;

+ +#endif

+ +      emit_ab(as, PPCI_CMPLW, type, tisnum);

+      }

+ -    if (ra_hasreg(dest)) emit_fai(as, PPCI_LFD, dest, base, ofs-4);

+ +    if (ra_hasreg(dest)) emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest,

+ +				  base, ofs-(LJ_SOFTFP?0:4));

+    } else {

+      if ((ir->op2 & IRSLOAD_TYPECHECK)) {

+        asm_guardcc(as, CC_NE);

+ @@ -1119,6 +1225,7 @@ static void asm_obar(ASMState *as, IRIns *ir)

+  

+  /* -- Arithmetic and logic operations ------------------------------------- */

+  

+ +#if !LJ_SOFTFP

+  static void asm_fparith(ASMState *as, IRIns *ir, PPCIns pi)

+  {

+    Reg dest = ra_dest(as, ir, RSET_FPR);

+ @@ -1146,13 +1253,17 @@ static void asm_fpmath(ASMState *as, IRIns *ir)

+    else

+      asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);

+  }

+ +#endif

+  

+  static void asm_add(ASMState *as, IRIns *ir)

+  {

+ +#if !LJ_SOFTFP

+    if (irt_isnum(ir->t)) {

+      if (!asm_fusemadd(as, ir, PPCI_FMADD, PPCI_FMADD))

+        asm_fparith(as, ir, PPCI_FADD);

+ -  } else {

+ +  } else

+ +#endif

+ +  {

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+      Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);

+      PPCIns pi;

+ @@ -1191,10 +1302,13 @@ static void asm_add(ASMState *as, IRIns *ir)

+  

+  static void asm_sub(ASMState *as, IRIns *ir)

+  {

+ +#if !LJ_SOFTFP

+    if (irt_isnum(ir->t)) {

+      if (!asm_fusemadd(as, ir, PPCI_FMSUB, PPCI_FNMSUB))

+        asm_fparith(as, ir, PPCI_FSUB);

+ -  } else {

+ +  } else

+ +#endif

+ +  {

+      PPCIns pi = PPCI_SUBF;

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+      Reg left, right;

+ @@ -1220,9 +1334,12 @@ static void asm_sub(ASMState *as, IRIns *ir)

+  

+  static void asm_mul(ASMState *as, IRIns *ir)

+  {

+ +#if !LJ_SOFTFP

+    if (irt_isnum(ir->t)) {

+      asm_fparith(as, ir, PPCI_FMUL);

+ -  } else {

+ +  } else

+ +#endif

+ +  {

+      PPCIns pi = PPCI_MULLW;

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+      Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);

+ @@ -1250,9 +1367,12 @@ static void asm_mul(ASMState *as, IRIns *ir)

+  

+  static void asm_neg(ASMState *as, IRIns *ir)

+  {

+ +#if !LJ_SOFTFP

+    if (irt_isnum(ir->t)) {

+      asm_fpunary(as, ir, PPCI_FNEG);

+ -  } else {

+ +  } else

+ +#endif

+ +  {

+      Reg dest, left;

+      PPCIns pi = PPCI_NEG;

+      if (as->flagmcp == as->mcp) {

+ @@ -1563,9 +1683,40 @@ static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)

+  		       PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))

+  #define asm_bror(as, ir)	lua_assert(0)

+  

+ +#if LJ_SOFTFP

+ +static void asm_sfpmin_max(ASMState *as, IRIns *ir)

+ +{

+ +  CCallInfo ci = lj_ir_callinfo[IRCALL_softfp_cmp];

+ +  IRRef args[4];

+ +  MCLabel l_right, l_end;

+ +  Reg desthi = ra_dest(as, ir, RSET_GPR), destlo = ra_dest(as, ir+1, RSET_GPR);

+ +  Reg righthi, lefthi = ra_alloc2(as, ir, RSET_GPR);

+ +  Reg rightlo, leftlo = ra_alloc2(as, ir+1, RSET_GPR);

+ +  PPCCC cond = (IROp)ir->o == IR_MIN ? CC_EQ : CC_NE;

+ +  righthi = (lefthi >> 8); lefthi &= 255;

+ +  rightlo = (leftlo >> 8); leftlo &= 255;

+ +  args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;

+ +  args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;

+ +  l_end = emit_label(as);

+ +  if (desthi != righthi) emit_mr(as, desthi, righthi);

+ +  if (destlo != rightlo) emit_mr(as, destlo, rightlo);

+ +  l_right = emit_label(as);

+ +  if (l_end != l_right) emit_jmp(as, l_end);

+ +  if (desthi != lefthi) emit_mr(as, desthi, lefthi);

+ +  if (destlo != leftlo) emit_mr(as, destlo, leftlo);

+ +  if (l_right == as->mcp+1) {

+ +    cond ^= 4; l_right = l_end; ++as->mcp;

+ +  }

+ +  emit_condbranch(as, PPCI_BC, cond, l_right);

+ +  ra_evictset(as, RSET_SCRATCH);

+ +  emit_cmpi(as, RID_RET, 1);

+ +  asm_gencall(as, &ci, args);

+ +}

+ +#endif

+ +

+  static void asm_min_max(ASMState *as, IRIns *ir, int ismax)

+  {

+ -  if (irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+      Reg dest = ra_dest(as, ir, RSET_FPR);

+      Reg tmp = dest;

+      Reg right, left = ra_alloc2(as, ir, RSET_FPR);

+ @@ -1653,7 +1804,7 @@ static void asm_intcomp_(ASMState *as, IRRef lref, IRRef rref, Reg cr, PPCCC cc)

+  static void asm_comp(ASMState *as, IRIns *ir)

+  {

+    PPCCC cc = asm_compmap[ir->o];

+ -  if (irt_isnum(ir->t)) {

+ +  if (!LJ_SOFTFP && irt_isnum(ir->t)) {

+      Reg right, left = ra_alloc2(as, ir, RSET_FPR);

+      right = (left >> 8); left &= 255;

+      asm_guardcc(as, (cc >> 4));

+ @@ -1674,6 +1825,44 @@ static void asm_comp(ASMState *as, IRIns *ir)

+  

+  #define asm_equal(as, ir)	asm_comp(as, ir)

+  

+ +#if LJ_SOFTFP

+ +/* SFP comparisons. */

+ +static void asm_sfpcomp(ASMState *as, IRIns *ir)

+ +{

+ +  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];

+ +  RegSet drop = RSET_SCRATCH;

+ +  Reg r;

+ +  IRRef args[4];

+ +  args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;

+ +  args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;

+ +

+ +  for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) {

+ +    if (!rset_test(as->freeset, r) &&

+ +	regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR])

+ +      rset_clear(drop, r);

+ +  }

+ +  ra_evictset(as, drop);

+ +  asm_setupresult(as, ir, ci);

+ +  switch ((IROp)ir->o) {

+ +  case IR_ULT:

+ +    asm_guardcc(as, CC_EQ);

+ +    emit_ai(as, PPCI_CMPWI, RID_RET, 0);

+ +  case IR_ULE:

+ +    asm_guardcc(as, CC_EQ);

+ +    emit_ai(as, PPCI_CMPWI, RID_RET, 1);

+ +    break;

+ +  case IR_GE: case IR_GT:

+ +    asm_guardcc(as, CC_EQ);

+ +    emit_ai(as, PPCI_CMPWI, RID_RET, 2);

+ +  default:

+ +    asm_guardcc(as, (asm_compmap[ir->o] & 0xf));

+ +    emit_ai(as, PPCI_CMPWI, RID_RET, 0);

+ +    break;

+ +  }

+ +  asm_gencall(as, ci, args);

+ +}

+ +#endif

+ +

+  #if LJ_HASFFI

+  /* 64 bit integer comparisons. */

+  static void asm_comp64(ASMState *as, IRIns *ir)

+ @@ -1703,19 +1892,36 @@ static void asm_comp64(ASMState *as, IRIns *ir)

+  /* Hiword op of a split 64 bit op. Previous op must be the loword op. */

+  static void asm_hiop(ASMState *as, IRIns *ir)

+  {

+ -#if LJ_HASFFI

+ +#if LJ_HASFFI || LJ_SOFTFP

+    /* HIOP is marked as a store because it needs its own DCE logic. */

+    int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */

+    if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;

+    if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */

+      as->curins--;  /* Always skip the CONV. */

+ +#if LJ_HASFFI && !LJ_SOFTFP

+      if (usehi || uselo)

+        asm_conv64(as, ir);

+      return;

+ +#endif

+    } else if ((ir-1)->o <= IR_NE) {  /* 64 bit integer comparisons. ORDER IR. */

+      as->curins--;  /* Always skip the loword comparison. */

+ +#if LJ_SOFTFP

+ +    if (!irt_isint(ir->t)) {

+ +      asm_sfpcomp(as, ir-1);

+ +      return;

+ +    }

+ +#endif

+ +#if LJ_HASFFI

+      asm_comp64(as, ir);

+ +#endif

+ +    return;

+ +#if LJ_SOFTFP

+ +  } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {

+ +      as->curins--;  /* Always skip the loword min/max. */

+ +    if (uselo || usehi)

+ +      asm_sfpmin_max(as, ir-1);

+      return;

+ +#endif

+    } else if ((ir-1)->o == IR_XSTORE) {

+      as->curins--;  /* Handle both stores here. */

+      if ((ir-1)->r != RID_SINK) {

+ @@ -1726,14 +1932,27 @@ static void asm_hiop(ASMState *as, IRIns *ir)

+    }

+    if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */

+    switch ((ir-1)->o) {

+ +#if LJ_HASFFI

+    case IR_ADD: as->curins--; asm_add64(as, ir); break;

+    case IR_SUB: as->curins--; asm_sub64(as, ir); break;

+    case IR_NEG: as->curins--; asm_neg64(as, ir); break;

+ +#endif

+ +#if LJ_SOFTFP

+ +  case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:

+ +  case IR_STRTO:

+ +    if (!uselo)

+ +      ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */

+ +    break;

+ +#endif

+    case IR_CALLN:

+ +  case IR_CALLS:

+    case IR_CALLXS:

+      if (!uselo)

+        ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */

+      break;

+ +#if LJ_SOFTFP

+ +  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:

+ +#endif

+    case IR_CNEWI:

+      /* Nothing to do here. Handled by lo op itself. */

+      break;

+ @@ -1797,8 +2016,19 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)

+      if ((sn & SNAP_NORESTORE))

+        continue;

+      if (irt_isnum(ir->t)) {

+ +#if LJ_SOFTFP

+ +      Reg tmp;

+ +      RegSet allow = rset_exclude(RSET_GPR, RID_BASE);

+ +      lua_assert(irref_isk(ref));  /* LJ_SOFTFP: must be a number constant. */

+ +      tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);

+ +      emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?4:0));

+ +      if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);

+ +      tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow);

+ +      emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?0:4));

+ +#else

+        Reg src = ra_alloc1(as, ref, RSET_FPR);

+        emit_fai(as, PPCI_STFD, src, RID_BASE, ofs);

+ +#endif

+      } else {

+        Reg type;

+        RegSet allow = rset_exclude(RSET_GPR, RID_BASE);

+ @@ -1811,6 +2041,10 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)

+        if ((sn & (SNAP_CONT|SNAP_FRAME))) {

+  	if (s == 0) continue;  /* Do not overwrite link to previous frame. */

+  	type = ra_allock(as, (int32_t)(*flinks--), allow);

+ +#if LJ_SOFTFP

+ +      } else if ((sn & SNAP_SOFTFPNUM)) {

+ +	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));

+ +#endif

+        } else {

+  	type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);

+        }

+ @@ -1947,14 +2181,15 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)

+    int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;

+    asm_collectargs(as, ir, ci, args);

+    for (i = 0; i < nargs; i++)

+ -    if (args[i] && irt_isfp(IR(args[i])->t)) {

+ +    if (!LJ_SOFTFP && args[i] && irt_isfp(IR(args[i])->t)) {

+        if (nfpr > 0) nfpr--; else nslots = (nslots+3) & ~1;

+      } else {

+        if (ngpr > 0) ngpr--; else nslots++;

+      }

+    if (nslots > as->evenspill)  /* Leave room for args in stack slots. */

+      as->evenspill = nslots;

+ -  return irt_isfp(ir->t) ? REGSP_HINT(RID_FPRET) : REGSP_HINT(RID_RET);

+ +  return (!LJ_SOFTFP && irt_isfp(ir->t)) ? REGSP_HINT(RID_FPRET) :

+ +					   REGSP_HINT(RID_RET);

+  }

+  

+  static void asm_setup_target(ASMState *as)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From 05fbdf565c700365d22e38f11478101a0d92a23e Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 10 Sep 2017 14:05:30 +0200

+ Subject: [PATCH 14/72] x64/LJ_GC64: Fix type-check-only variant of SLOAD.

+ 

+ Thanks to Peter Cawley.

+ ---

+  src/lj_asm_x86.h | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h

+ index 55c02d2..af54dc7 100644

+ --- a/src/lj_asm_x86.h

+ +++ b/src/lj_asm_x86.h

+ @@ -1759,7 +1759,7 @@ static void asm_sload(ASMState *as, IRIns *ir)

+        emit_i8(as, irt_toitype(t));

+        emit_rr(as, XO_ARITHi8, XOg_CMP, tmp);

+        emit_shifti(as, XOg_SAR|REX_64, tmp, 47);

+ -      emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs+4);

+ +      emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs);

+  #else

+      } else {

+        emit_i8(as, irt_toitype(t));

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From bf12f1dafb157008b963f829b57b2472b6993cc8 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 18 Sep 2017 09:50:22 +0200

+ Subject: [PATCH 15/72] MIPS64: Hide internal function.

+ 

+ ---

+  src/lj_ccall.c | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_ccall.c b/src/lj_ccall.c

+ index 799be48..25e938c 100644

+ --- a/src/lj_ccall.c

+ +++ b/src/lj_ccall.c

+ @@ -848,7 +848,8 @@ noth:  /* Not a homogeneous float/double aggregate. */

+    return 0;  /* Struct is in GPRs. */

+  }

+  

+ -void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp, int ft)

+ +static void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp,

+ +			      int ft)

+  {

+    if (LJ_ABI_SOFTFP ? ft :

+        ((ft & 3) == FTYPE_FLOAT || (ft >> 2) == FTYPE_FLOAT)) {

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,34 @@ 

+ commit 6a2d8b0b4d49eb5aac600c219e5903420806e56e

+ Merge: bf12f1d 0c0e7b1

+ Author: Mike Pall <mike>

+ Date:   Wed Sep 20 19:42:34 2017 +0200

+ 

+     Merge branch 'master' into v2.1

+ 

+ From 0c0e7b168ea147866835954267c151ef789f64fb Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 20 Sep 2017 19:39:50 +0200

+ Subject: [PATCH 16/72] DynASM/x86: Fix potential REL_A overflow.

+ 

+ Thanks to Joshua Haberman.

+ ---

+  dynasm/dasm_x86.h | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/dynasm/dasm_x86.h b/dynasm/dasm_x86.h

+ index 90dc5d1..f9260b0 100644

+ --- a/dynasm/dasm_x86.h

+ +++ b/dynasm/dasm_x86.h

+ @@ -395,7 +395,8 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	}

+  	case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;

+  	  b++; n = (int)(ptrdiff_t)D->globals[-n];

+ -	case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */

+ +	case DASM_REL_A: rel_a:

+ +	  n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */

+  	case DASM_REL_PC: rel_pc: {

+  	  int shrink = *b++;

+  	  int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,29 @@ 

+ From b4ed3219a1a98dd9fe7d1e3eeea3b82f5a780948 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 2 Oct 2017 09:22:46 +0200

+ Subject: [PATCH 17/72] LJ_GC64: Fix ir_khash for non-string GCobj.

+ 

+ Contributed by Peter Cawley.

+ ---

+  src/lj_asm.c | 4 ++++

+  1 file changed, 4 insertions(+)

+ 

+ diff --git a/src/lj_asm.c b/src/lj_asm.c

+ index bed2268..d961927 100644

+ --- a/src/lj_asm.c

+ +++ b/src/lj_asm.c

+ @@ -1017,7 +1017,11 @@ static uint32_t ir_khash(IRIns *ir)

+    } else {

+      lua_assert(irt_isgcv(ir->t));

+      lo = u32ptr(ir_kgc(ir));

+ +#if LJ_GC64

+ +    hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15);

+ +#else

+      hi = lo + HASH_BIAS;

+ +#endif

+    }

+    return hashrot(lo, hi);

+  }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,57 @@ 

+ From 850f8c59d3d04a9847f21f32a6c36d8269b5b6b1 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 2 Oct 2017 23:10:56 +0200

+ Subject: [PATCH 18/72] LJ_GC64: Make ASMREF_L references 64 bit.

+ 

+ Reported by Yichun Zhang.

+ ---

+  src/lj_asm.c      | 1 +

+  src/lj_ir.h       | 4 +++-

+  src/lj_opt_sink.c | 1 +

+  3 files changed, 5 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm.c b/src/lj_asm.c

+ index d961927..753fe6b 100644

+ --- a/src/lj_asm.c

+ +++ b/src/lj_asm.c

+ @@ -2015,6 +2015,7 @@ static void asm_setup_regsp(ASMState *as)

+      ir->prev = REGSP_INIT;

+      if (irt_is64(ir->t) && ir->o != IR_KNULL) {

+  #if LJ_GC64

+ +      /* The false-positive of irt_is64() for ASMREF_L (REF_NIL) is OK here. */

+        ir->i = 0;  /* Will become non-zero only for RIP-relative addresses. */

+  #else

+        /* Make life easier for backends by putting address of constant in i. */

+ diff --git a/src/lj_ir.h b/src/lj_ir.h

+ index 34c2785..8057a75 100644

+ --- a/src/lj_ir.h

+ +++ b/src/lj_ir.h

+ @@ -377,10 +377,12 @@ typedef struct IRType1 { uint8_t irt; } IRType1;

+  #define irt_isint64(t)		(irt_typerange((t), IRT_I64, IRT_U64))

+  

+  #if LJ_GC64

+ +/* Include IRT_NIL, so IR(ASMREF_L) (aka REF_NIL) is considered 64 bit. */

+  #define IRT_IS64 \

+    ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|\

+     (1u<<IRT_LIGHTUD)|(1u<<IRT_STR)|(1u<<IRT_THREAD)|(1u<<IRT_PROTO)|\

+ -   (1u<<IRT_FUNC)|(1u<<IRT_CDATA)|(1u<<IRT_TAB)|(1u<<IRT_UDATA))

+ +   (1u<<IRT_FUNC)|(1u<<IRT_CDATA)|(1u<<IRT_TAB)|(1u<<IRT_UDATA)|\

+ +   (1u<<IRT_NIL))

+  #elif LJ_64

+  #define IRT_IS64 \

+    ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|(1u<<IRT_LIGHTUD))

+ diff --git a/src/lj_opt_sink.c b/src/lj_opt_sink.c

+ index 929ccb6..a16d112 100644

+ --- a/src/lj_opt_sink.c

+ +++ b/src/lj_opt_sink.c

+ @@ -219,6 +219,7 @@ static void sink_sweep_ins(jit_State *J)

+    for (ir = IR(J->cur.nk); ir < irbase; ir++) {

+      irt_clearmark(ir->t);

+      ir->prev = REGSP_INIT;

+ +    /* The false-positive of irt_is64() for ASMREF_L (REF_NIL) is OK here. */

+      if (irt_is64(ir->t) && ir->o != IR_KNULL)

+        ir++;

+    }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From 9f0caad0e43f97a4613850b3874b851cb1bc301d Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 8 Nov 2017 12:53:05 +0100

+ Subject: [PATCH 19/72] Fix FOLD rule for strength reduction of widening.

+ 

+ Reported by Matthew Burk.

+ ---

+  src/lj_opt_fold.c | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c

+ index 3d0e35a..5dc7ae3 100644

+ --- a/src/lj_opt_fold.c

+ +++ b/src/lj_opt_fold.c

+ @@ -1052,7 +1052,7 @@ LJFOLDF(simplify_conv_sext)

+    if (ref == J->scev.idx) {

+      IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop;

+      lua_assert(irt_isint(J->scev.t));

+ -    if (lo && IR(lo)->i + ofs >= 0) {

+ +    if (lo && IR(lo)->o == IR_KINT && IR(lo)->i + ofs >= 0) {

+      ok_reduce:

+  #if LJ_TARGET_X64

+        /* Eliminate widening. All 32 bit ops do an implicit zero-extension. */

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,45 @@ 

+ From 06cd9fce7df440323647174f1ca4a01281ec8acd Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 8 Nov 2017 12:53:48 +0100

+ Subject: [PATCH 20/72] ARM64: Fix assembly of HREFK.

+ 

+ Reported by Jason Teplitz.

+ ---

+  src/lj_asm_arm64.h | 11 +++++------

+  1 file changed, 5 insertions(+), 6 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index 8fd92e7..cbb186d 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -869,14 +869,12 @@ static void asm_hrefk(ASMState *as, IRIns *ir)

+    int32_t ofs = (int32_t)(kslot->op2 * sizeof(Node));

+    int32_t kofs = ofs + (int32_t)offsetof(Node, key);

+    int bigofs = !emit_checkofs(A64I_LDRx, ofs);

+ -  RegSet allow = RSET_GPR;

+    Reg dest = (ra_used(ir) || bigofs) ? ra_dest(as, ir, RSET_GPR) : RID_NONE;

+ -  Reg node = ra_alloc1(as, ir->op1, allow);

+ -  Reg key = ra_scratch(as, rset_clear(allow, node));

+ -  Reg idx = node;

+ +  Reg node = ra_alloc1(as, ir->op1, RSET_GPR);

+ +  Reg key, idx = node;

+ +  RegSet allow = rset_exclude(RSET_GPR, node);

+    uint64_t k;

+    lua_assert(ofs % sizeof(Node) == 0);

+ -  rset_clear(allow, key);

+    if (bigofs) {

+      idx = dest;

+      rset_clear(allow, dest);

+ @@ -892,7 +890,8 @@ static void asm_hrefk(ASMState *as, IRIns *ir)

+    } else {

+      k = ((uint64_t)irt_toitype(irkey->t) << 47) | (uint64_t)ir_kgc(irkey);

+    }

+ -  emit_nm(as, A64I_CMPx, key, ra_allock(as, k, allow));

+ +  key = ra_scratch(as, allow);

+ +  emit_nm(as, A64I_CMPx, key, ra_allock(as, k, rset_exclude(allow, key)));

+    emit_lso(as, A64I_LDRx, key, idx, kofs);

+    if (bigofs)

+      emit_opk(as, A64I_ADDx, dest, node, ofs, RSET_GPR);

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,81 @@ 

+ From 99cdfbf6a1e8856f64908072ef10443a7eab14f2 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 8 Nov 2017 12:54:03 +0100

+ Subject: [PATCH 21/72] MIPS64: Fix register allocation in assembly of HREF.

+ 

+ Contributed by James Cowgill.

+ ---

+  src/lj_asm_mips.h | 42 +++++++++++++++++++++++++-----------------

+  1 file changed, 25 insertions(+), 17 deletions(-)

+ 

+ diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h

+ index 1406a87..3a4679b 100644

+ --- a/src/lj_asm_mips.h

+ +++ b/src/lj_asm_mips.h

+ @@ -859,6 +859,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+    Reg dest = ra_dest(as, ir, allow);

+    Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));

+    Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2;

+ +#if LJ_64

+ +  Reg cmp64 = RID_NONE;

+ +#endif

+    IRRef refkey = ir->op2;

+    IRIns *irkey = IR(refkey);

+    int isk = irref_isk(refkey);

+ @@ -901,6 +904,26 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+  #endif

+    tmp2 = ra_scratch(as, allow);

+    rset_clear(allow, tmp2);

+ +#if LJ_64

+ +  if (LJ_SOFTFP || !irt_isnum(kt)) {

+ +    /* Allocate cmp64 register used for 64-bit comparisons */

+ +    if (LJ_SOFTFP && irt_isnum(kt)) {

+ +      cmp64 = key;

+ +    } else if (!isk && irt_isaddr(kt)) {

+ +      cmp64 = tmp2;

+ +    } else {

+ +      int64_t k;

+ +      if (isk && irt_isaddr(kt)) {

+ +	k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;

+ +      } else {

+ +	lua_assert(irt_ispri(kt) && !irt_isnil(kt));

+ +	k = ~((int64_t)~irt_toitype(ir->t) << 47);

+ +      }

+ +      cmp64 = ra_allock(as, k, allow);

+ +      rset_clear(allow, cmp64);

+ +    }

+ +  }

+ +#endif

+  

+    /* Key not found in chain: jump to exit (if merged) or load niltv. */

+    l_end = emit_label(as);

+ @@ -943,24 +966,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)

+      emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);

+      emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);

+      emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));

+ -  } else if (LJ_SOFTFP && irt_isnum(kt)) {

+ -    emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);

+ -    emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));

+ -  } else if (irt_isaddr(kt)) {

+ -    Reg refk = tmp2;

+ -    if (isk) {

+ -      int64_t k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;

+ -      refk = ra_allock(as, k, allow);

+ -      rset_clear(allow, refk);

+ -    }

+ -    emit_branch(as, MIPSI_BEQ, tmp1, refk, l_end);

+ -    emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));

+    } else {

+ -    Reg pri = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow);

+ -    rset_clear(allow, pri);

+ -    lua_assert(irt_ispri(kt) && !irt_isnil(kt));

+ -    emit_branch(as, MIPSI_BEQ, tmp1, pri, l_end);

+ -    emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));

+ +    emit_branch(as, MIPSI_BEQ, tmp1, cmp64, l_end);

+ +    emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));

+    }

+    *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu);

+    if (!isk && irt_isaddr(kt)) {

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,31 @@ 

+ From 33082a6f4778aa152f6a4a684a7fe79436f1ecb6 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 16 Nov 2017 12:53:34 +0100

+ Subject: [PATCH 22/72] ARM64: Fix xpcall() error case.

+ 

+ Thanks to Stefan Pejic.

+ ---

+  src/vm_arm64.dasc | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc

+ index 3eaf376..241c58a 100644

+ --- a/src/vm_arm64.dasc

+ +++ b/src/vm_arm64.dasc

+ @@ -1185,12 +1185,12 @@ static void build_subroutines(BuildCtx *ctx)

+    |   subs NARGS8:RC, NARGS8:RC, #16

+    |   blo ->fff_fallback

+    |    mov RB, BASE

+ -  |    add BASE, BASE, #24

+    |     asr ITYPE, CARG2, #47

+    |  ubfx TMP0w, TMP0w, #HOOK_ACTIVE_SHIFT, #1

+    |     cmn ITYPE, #-LJ_TFUNC

+    |  add PC, TMP0, #24+FRAME_PCALL

+    |     bne ->fff_fallback		// Traceback must be a function.

+ +  |    add BASE, BASE, #24

+    |     stp CARG2, CARG1, [RB]		// Swap function and traceback.

+    |   cbz NARGS8:RC, ->vm_call_dispatch

+    |  b <1

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From 7dbf0b05f1228c1c719866db5e5f3d58f87f74c8 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 16 Nov 2017 12:58:12 +0100

+ Subject: [PATCH 23/72] Fix saved bytecode encapsulated in ELF objects.

+ 

+ Thanks to Dimitry Andric.

+ ---

+  src/jit/bcsave.lua | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua

+ index aa677df..c94064e 100644

+ --- a/src/jit/bcsave.lua

+ +++ b/src/jit/bcsave.lua

+ @@ -275,7 +275,7 @@ typedef struct {

+    o.sect[2].size = fofs(ofs)

+    o.sect[3].type = f32(3) -- .strtab

+    o.sect[3].ofs = fofs(sofs + ofs)

+ -  o.sect[3].size = fofs(#symname+1)

+ +  o.sect[3].size = fofs(#symname+2)

+    ffi.copy(o.space+ofs+1, symname)

+    ofs = ofs + #symname + 2

+    o.sect[4].type = f32(1) -- .rodata

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,37 @@ 

+ From d417ded17945b4211608d497d50b509e0274f5e0 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sat, 18 Nov 2017 12:23:57 +0100

+ Subject: [PATCH 24/72] ARM64: Fix xpcall() error case (really).

+ MIME-Version: 1.0

+ Content-Type: text/plain; charset=UTF-8

+ Content-Transfer-Encoding: 8bit

+ 

+ Thanks to François Perrad and Stefan Pejic.

+ ---

+  src/vm_arm64.dasc | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc

+ index 241c58a..c55794a 100644

+ --- a/src/vm_arm64.dasc

+ +++ b/src/vm_arm64.dasc

+ @@ -1182,7 +1182,7 @@ static void build_subroutines(BuildCtx *ctx)

+    |.ffunc xpcall

+    |     ldp CARG1, CARG2, [BASE]

+    |  ldrb TMP0w, GL->hookmask

+ -  |   subs NARGS8:RC, NARGS8:RC, #16

+ +  |   subs NARGS8:TMP1, NARGS8:RC, #16

+    |   blo ->fff_fallback

+    |    mov RB, BASE

+    |     asr ITYPE, CARG2, #47

+ @@ -1190,6 +1190,7 @@ static void build_subroutines(BuildCtx *ctx)

+    |     cmn ITYPE, #-LJ_TFUNC

+    |  add PC, TMP0, #24+FRAME_PCALL

+    |     bne ->fff_fallback		// Traceback must be a function.

+ +  |   mov NARGS8:RC, NARGS8:TMP1

+    |    add BASE, BASE, #24

+    |     stp CARG2, CARG1, [RB]		// Swap function and traceback.

+    |   cbz NARGS8:RC, ->vm_call_dispatch

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,39 @@ 

+ From ea7071d3c30b6432bfe6f8a9d263e0285cec25e3 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sat, 18 Nov 2017 12:25:35 +0100

+ Subject: [PATCH 25/72] MIPS64: Fix xpcall() error case.

+ MIME-Version: 1.0

+ Content-Type: text/plain; charset=UTF-8

+ Content-Transfer-Encoding: 8bit

+ 

+ Thanks to François Perrad and Stefan Pejic.

+ ---

+  src/vm_mips64.dasc | 5 +++--

+  1 file changed, 3 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc

+ index 75b38de..a78cd25 100644

+ --- a/src/vm_mips64.dasc

+ +++ b/src/vm_mips64.dasc

+ @@ -1399,15 +1399,16 @@ static void build_subroutines(BuildCtx *ctx)

+    |.  nop

+    |

+    |.ffunc xpcall

+ -  |  daddiu NARGS8:RC, NARGS8:RC, -16

+ +  |  daddiu NARGS8:TMP0, NARGS8:RC, -16

+    |  ld CARG1, 0(BASE)

+    |   ld CARG2, 8(BASE)

+ -  |    bltz NARGS8:RC, ->fff_fallback

+ +  |    bltz NARGS8:TMP0, ->fff_fallback

+    |.    lbu TMP1, DISPATCH_GL(hookmask)(DISPATCH)

+    |  gettp AT, CARG2

+    |  daddiu AT, AT, -LJ_TFUNC

+    |  bnez AT, ->fff_fallback		// Traceback must be a function.

+    |.   move TMP2, BASE

+ +  |  move NARGS8:RC, NARGS8:TMP0

+    |   daddiu BASE, BASE, 24

+    |  // Remember active hook before pcall.

+    |  srl TMP3, TMP3, HOOK_ACTIVE_SHIFT

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,44 @@ 

+ From 58d0dde0a2df49abc991decbabff15230010829a Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 14 Jan 2018 13:57:00 +0100

+ Subject: [PATCH 26/72] Fix IR_BUFPUT assembly.

+ 

+ Thanks to Peter Cawley.

+ ---

+  src/lj_asm.c | 6 +++---

+  1 file changed, 3 insertions(+), 3 deletions(-)

+ 

+ diff --git a/src/lj_asm.c b/src/lj_asm.c

+ index 753fe6b..5f83779 100644

+ --- a/src/lj_asm.c

+ +++ b/src/lj_asm.c

+ @@ -1119,7 +1119,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)

+    const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr];

+    IRRef args[3];

+    IRIns *irs;

+ -  int kchar = -1;

+ +  int kchar = -129;

+    args[0] = ir->op1;  /* SBuf * */

+    args[1] = ir->op2;  /* GCstr * */

+    irs = IR(ir->op2);

+ @@ -1127,7 +1127,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)

+    if (irs->o == IR_KGC) {

+      GCstr *s = ir_kstr(irs);

+      if (s->len == 1) {  /* Optimize put of single-char string constant. */

+ -      kchar = strdata(s)[0];

+ +      kchar = (int8_t)strdata(s)[0];  /* Signed! */

+        args[1] = ASMREF_TMP1;  /* int, truncated to char */

+        ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];

+      }

+ @@ -1154,7 +1154,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)

+    asm_gencall(as, ci, args);

+    if (args[1] == ASMREF_TMP1) {

+      Reg tmp = ra_releasetmp(as, ASMREF_TMP1);

+ -    if (kchar == -1)

+ +    if (kchar == -129)

+        asm_tvptr(as, tmp, irs->op1);

+      else

+        ra_allockreg(as, kchar, tmp);

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,15 @@ 

+ commit 4660dbfa8a4f9eea5218b739075d04faadfeeef6

+ Merge: 58d0dde 430d9f8

+ Author: Mike Pall <mike>

+ Date:   Sun Jan 14 14:26:10 2018 +0100

+ 

+     Merge branch 'master' into v2.1

+ 

+ From 430d9f8f7ebb779948dbd43944b876b1a3f58551 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 14 Jan 2018 14:11:59 +0100

+ Subject: [PATCH 27/72] Fix string.format("%c", 0).

+ 

+ ---

+  src/lib_string.c | 15 ++++++++-------

+  1 file changed, 8 insertions(+), 7 deletions(-)

@@ -0,0 +1,26 @@ 

+ From 9eaad8574f5b2271b981cd31966b1e832cd8de12 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 18 Jan 2018 12:24:36 +0100

+ Subject: [PATCH 28/72] Fix ARMv8 (32 bit subset) detection.

+ 

+ Thanks to Markus Oberhumber.

+ ---

+  src/lj_arch.h | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_arch.h b/src/lj_arch.h

+ index 5962f3a..fcebd84 100644

+ --- a/src/lj_arch.h

+ +++ b/src/lj_arch.h

+ @@ -201,7 +201,7 @@

+  #define LJ_TARGET_UNIFYROT	2	/* Want only IR_BROR. */

+  #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL

+  

+ -#if __ARM_ARCH____ARM_ARCH_8__ || __ARM_ARCH_8A__

+ +#if __ARM_ARCH_8__ || __ARM_ARCH_8A__

+  #define LJ_ARCH_VERSION		80

+  #elif __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ || __ARM_ARCH_7VE__

+  #define LJ_ARCH_VERSION		70

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,28 @@ 

+ From c88602f080dcafea6ba222a2f7cc1ea0e41ef3cc Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 18 Jan 2018 12:29:39 +0100

+ Subject: [PATCH 29/72] Fix LuaJIT API docs for LUAJIT_MODE_*.

+ 

+ Thanks to sunfishgao.

+ ---

+  doc/ext_c_api.html | 4 ++--

+  1 file changed, 2 insertions(+), 2 deletions(-)

+ 

+ diff --git a/doc/ext_c_api.html b/doc/ext_c_api.html

+ index 041a722..4bb8251 100644

+ --- a/doc/ext_c_api.html

+ +++ b/doc/ext_c_api.html

+ @@ -89,8 +89,8 @@ other Lua/C API functions).

+  </p>

+  <p>

+  The third argument specifies the mode, which is 'or'ed with a flag.

+ -The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature on,

+ -<tt>LUAJIT_MODE_ON</tt> to turn a feature off, or

+ +The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature off,

+ +<tt>LUAJIT_MODE_ON</tt> to turn a feature on, or

+  <tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.

+  </p>

+  <p>

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From 8071aa4ad65cf09e3b7adda4a7787d8897e5314c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 29 Jan 2018 12:12:29 +0100

+ Subject: [PATCH 30/72] MIPS64: Fix soft-float +-0.0 vs. +-0.0 comparison.

+ 

+ Thanks to Stefan Pejic.

+ ---

+  src/vm_mips64.dasc | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc

+ index a78cd25..0a3f8e5 100644

+ --- a/src/vm_mips64.dasc

+ +++ b/src/vm_mips64.dasc

+ @@ -2661,7 +2661,7 @@ static void build_subroutines(BuildCtx *ctx)

+    |.  slt CRET1, CARG2, CARG1

+    |8:

+    |  jr ra

+ -  |.  nop

+ +  |.  li CRET1, 0

+    |9:

+    |  jr ra

+    |.  move CRET1, CRET2

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,69 @@ 

+ commit 74c544d68c07bcd416225598cdf15f88e62fd457

+ Merge: 8071aa4 b03a56f

+ Author: Mike Pall <mike>

+ Date:   Mon Jan 29 12:53:42 2018 +0100

+ 

+     Merge branch 'master' into v2.1

+ 

+ From b03a56f28ec360bbcf43091afd0607890a4a33c7 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 29 Jan 2018 12:47:08 +0100

+ Subject: [PATCH 31/72] FFI: Don't assert on #1LL (5.2 compatibility mode

+  only).

+ 

+ Reported by Denis Golovan.

+ ---

+  src/lib_ffi.c   | 2 +-

+  src/lj_carith.c | 9 +++++++++

+  src/lj_carith.h | 1 +

+  3 files changed, 11 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lib_ffi.c b/src/lib_ffi.c

+ index f2f2ede..83483d9 100644

+ --- a/src/lib_ffi.c

+ +++ b/src/lib_ffi.c

+ @@ -193,7 +193,7 @@ LJLIB_CF(ffi_meta___eq)		LJLIB_REC(cdata_arith MM_eq)

+  

+  LJLIB_CF(ffi_meta___len)	LJLIB_REC(cdata_arith MM_len)

+  {

+ -  return ffi_arith(L);

+ +  return lj_carith_len(L);

+  }

+  

+  LJLIB_CF(ffi_meta___lt)		LJLIB_REC(cdata_arith MM_lt)

+ diff --git a/src/lj_carith.c b/src/lj_carith.c

+ index 6224dee..c34596c 100644

+ --- a/src/lj_carith.c

+ +++ b/src/lj_carith.c

+ @@ -272,6 +272,15 @@ int lj_carith_op(lua_State *L, MMS mm)

+    return lj_carith_meta(L, cts, &ca, mm);

+  }

+  

+ +/* No built-in functionality for length of cdata. */

+ +int lj_carith_len(lua_State *L)

+ +{

+ +  CTState *cts = ctype_cts(L);

+ +  CDArith ca;

+ +  carith_checkarg(L, cts, &ca);

+ +  return lj_carith_meta(L, cts, &ca, MM_len);

+ +}

+ +

+  /* -- 64 bit bit operations helpers --------------------------------------- */

+  

+  #if LJ_64

+ diff --git a/src/lj_carith.h b/src/lj_carith.h

+ index 3c15591..82fc824 100644

+ --- a/src/lj_carith.h

+ +++ b/src/lj_carith.h

+ @@ -11,6 +11,7 @@

+  #if LJ_HASFFI

+  

+  LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);

+ +LJ_FUNC int lj_carith_len(lua_State *L);

+  

+  #if LJ_32

+  LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);

+ 

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,291 @@ 

+ commit 0bf46e1edf94c43795b5e491efe682ab70974ce7

+ Merge: 74c544d d4ee803

+ Author: Mike Pall <mike>

+ Date:   Mon Jan 29 13:19:30 2018 +0100

+ 

+     Merge branch 'master' into v2.1

+ 

+ From d4ee80342770d1281e2ce877f8ae8ab1d99e6528 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 29 Jan 2018 13:06:13 +0100

+ Subject: [PATCH 32/72] Fix GCC 7 -Wimplicit-fallthrough warnings.

+ 

+ ---

+  dynasm/dasm_arm.h  |  2 ++

+  dynasm/dasm_mips.h |  1 +

+  dynasm/dasm_ppc.h  |  1 +

+  dynasm/dasm_x86.h  | 14 ++++++++++++--

+  src/lj_asm.c       |  3 ++-

+  src/lj_cparse.c    | 10 ++++++++++

+  src/lj_err.c       |  1 +

+  src/lj_opt_sink.c  |  2 +-

+  src/lj_parse.c     |  3 ++-

+  src/luajit.c       |  1 +

+  10 files changed, 33 insertions(+), 5 deletions(-)

+ 

+ diff --git a/dynasm/dasm_arm.h b/dynasm/dasm_arm.h

+ index a43f7c6..1d404cc 100644

+ --- a/dynasm/dasm_arm.h

+ +++ b/dynasm/dasm_arm.h

+ @@ -254,6 +254,7 @@ void dasm_put(Dst_DECL, int start, ...)

+        case DASM_IMMV8:

+  	CK((n & 3) == 0, RANGE_I);

+  	n >>= 2;

+ +	/* fallthrough */

+        case DASM_IMML8:

+        case DASM_IMML12:

+  	CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :

+ @@ -371,6 +372,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	  break;

+  	case DASM_REL_LG:

+  	  CK(n >= 0, UNDEF_LG);

+ +	  /* fallthrough */

+  	case DASM_REL_PC:

+  	  CK(n >= 0, UNDEF_PC);

+  	  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;

+ diff --git a/dynasm/dasm_mips.h b/dynasm/dasm_mips.h

+ index 7eac669..46af034 100644

+ --- a/dynasm/dasm_mips.h

+ +++ b/dynasm/dasm_mips.h

+ @@ -350,6 +350,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	  break;

+  	case DASM_REL_LG:

+  	  CK(n >= 0, UNDEF_LG);

+ +	  /* fallthrough */

+  	case DASM_REL_PC:

+  	  CK(n >= 0, UNDEF_PC);

+  	  n = *DASM_POS2PTR(D, n);

+ diff --git a/dynasm/dasm_ppc.h b/dynasm/dasm_ppc.h

+ index 6110361..81b9a76 100644

+ --- a/dynasm/dasm_ppc.h

+ +++ b/dynasm/dasm_ppc.h

+ @@ -350,6 +350,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	  break;

+  	case DASM_REL_LG:

+  	  CK(n >= 0, UNDEF_LG);

+ +	  /* fallthrough */

+  	case DASM_REL_PC:

+  	  CK(n >= 0, UNDEF_PC);

+  	  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);

+ diff --git a/dynasm/dasm_x86.h b/dynasm/dasm_x86.h

+ index f9260b0..8ae911d 100644

+ --- a/dynasm/dasm_x86.h

+ +++ b/dynasm/dasm_x86.h

+ @@ -194,12 +194,13 @@ void dasm_put(Dst_DECL, int start, ...)

+        switch (action) {

+        case DASM_DISP:

+  	if (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }

+ -      case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;

+ +	/* fallthrough */

+ +      case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */

+        case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */

+        case DASM_IMM_D: ofs += 4; break;

+        case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;

+        case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;

+ -      case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;

+ +      case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */

+        case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;

+        case DASM_SPACE: p++; ofs += n; break;

+        case DASM_SETLABEL: b[pos-2] = -0x40000000; break;  /* Neg. label ofs. */

+ @@ -323,11 +324,14 @@ int dasm_link(Dst_DECL, size_t *szp)

+  	  pos += 2;

+  	  break;

+  	}

+ +	  /* fallthrough */

+  	case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;

+ +	  /* fallthrough */

+  	case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:

+  	case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:

+  	case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;

+  	case DASM_LABEL_LG: p++;

+ +	  /* fallthrough */

+  	case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */

+  	case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */

+  	case DASM_EXTERN: p += 2; break;

+ @@ -385,12 +389,15 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	    if (mrm != 5) { mm[-1] -= 0x80; break; } }

+  	  if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;

+  	}

+ +	  /* fallthrough */

+  	case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;

+  	case DASM_IMM_DB: if (((n+128)&-256) == 0) {

+  	    db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;

+  	  } else mark = NULL;

+ +	  /* fallthrough */

+  	case DASM_IMM_D: wd: dasmd(n); break;

+  	case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;

+ +	  /* fallthrough */

+  	case DASM_IMM_W: dasmw(n); break;

+  	case DASM_VREG: {

+  	  int t = *p++;

+ @@ -397,6 +404,7 @@

+  	}

+  	case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;

+  	  b++; n = (int)(ptrdiff_t)D->globals[-n];

+ +	  /* fallthrough */

+  	case DASM_REL_A: rel_a:

+  	  n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */

+  	case DASM_REL_PC: rel_pc: {

+ @@ -407,6 +415,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	}

+  	case DASM_IMM_LG:

+  	  p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }

+ +	  /* fallthrough */

+  	case DASM_IMM_PC: {

+  	  int *pb = DASM_POS2PTR(D, n);

+  	  n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);

+ @@ -427,6 +436,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;

+  	case DASM_MARK: mark = cp; break;

+  	case DASM_ESC: action = *p++;

+ +	  /* fallthrough */

+  	default: *cp++ = action; break;

+  	case DASM_SECTION: case DASM_STOP: goto stop;

+  	}

+ diff --git a/src/lj_asm.c b/src/lj_asm.c

+ index 02714d4..dd7186f 100644

+ --- a/src/lj_asm.c

+ +++ b/src/lj_asm.c

+ @@ -2136,6 +2136,7 @@ static void asm_setup_regsp(ASMState *as)

+      case IR_SNEW: case IR_XSNEW: case IR_NEWREF: case IR_BUFPUT:

+        if (REGARG_NUMGPR < 3 && as->evenspill < 3)

+  	as->evenspill = 3;  /* lj_str_new and lj_tab_newkey need 3 args. */

+ +      /* fallthrough */

+  #if LJ_TARGET_X86 && LJ_HASFFI

+        if (0) {

+      case IR_CNEW:

+ @@ -2176,7 +2177,7 @@ static void asm_setup_regsp(ASMState *as)

+  	continue;

+  #endif

+        }

+ -      /* fallthrough for integer POW */

+ +      /* fallthrough */ /* for integer POW */

+      case IR_DIV: case IR_MOD:

+        if (!irt_isnum(ir->t)) {

+  	ir->prev = REGSP_HINT(RID_RET);

+ diff --git a/src/lj_cparse.c b/src/lj_cparse.c

+ index 2ba50a7..f111537 100644

+ --- a/src/lj_cparse.c

+ +++ b/src/lj_cparse.c

+ @@ -590,28 +590,34 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)

+  	k->id = k2.id > k3.id ? k2.id : k3.id;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 1:

+        if (cp_opt(cp, CTOK_OROR)) {

+  	cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 2:

+        if (cp_opt(cp, CTOK_ANDAND)) {

+  	cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 3:

+        if (cp_opt(cp, '|')) {

+  	cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result;

+        }

+ +      /* fallthrough */

+      case 4:

+        if (cp_opt(cp, '^')) {

+  	cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result;

+        }

+ +      /* fallthrough */

+      case 5:

+        if (cp_opt(cp, '&')) {

+  	cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result;

+        }

+ +      /* fallthrough */

+      case 6:

+        if (cp_opt(cp, CTOK_EQ)) {

+  	cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;

+ @@ -620,6 +626,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)

+  	cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 7:

+        if (cp_opt(cp, '<')) {

+  	cp_expr_sub(cp, &k2, 8);

+ @@ -654,6 +661,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)

+  	k->id = CTID_INT32;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 8:

+        if (cp_opt(cp, CTOK_SHL)) {

+  	cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;

+ @@ -666,6 +674,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)

+  	  k->u32 = k->u32 >> k2.u32;

+  	continue;

+        }

+ +      /* fallthrough */

+      case 9:

+        if (cp_opt(cp, '+')) {

+  	cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;

+ @@ -675,6 +684,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri)

+        } else if (cp_opt(cp, '-')) {

+  	cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;

+        }

+ +      /* fallthrough */

+      case 10:

+        if (cp_opt(cp, '*')) {

+  	cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result;

+ diff --git a/src/lj_err.c b/src/lj_err.c

+ index 54f42c3..13a1ded 100644

+ --- a/src/lj_err.c

+ +++ b/src/lj_err.c

+ @@ -153,6 +153,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)

+      case FRAME_CONT:  /* Continuation frame. */

+        if (frame_iscont_fficb(frame))

+  	goto unwind_c;

+ +      /* fallthrough */

+      case FRAME_VARG:  /* Vararg frame. */

+        frame = frame_prevd(frame);

+        break;

+ diff --git a/src/lj_opt_sink.c b/src/lj_opt_sink.c

+ index 6a00d04..4efe395 100644

+ --- a/src/lj_opt_sink.c

+ +++ b/src/lj_opt_sink.c

+ @@ -100,8 +100,8 @@ static void sink_mark_ins(jit_State *J)

+  	   (LJ_32 && ir+1 < irlast && (ir+1)->o == IR_HIOP &&

+  	    !sink_checkphi(J, ir, (ir+1)->op2))))

+  	irt_setmark(ir->t);  /* Mark ineligible allocation. */

+ -      /* fallthrough */

+  #endif

+ +      /* fallthrough */

+      case IR_USTORE:

+        irt_setmark(IR(ir->op2)->t);  /* Mark stored value. */

+        break;

+ diff --git a/src/lj_parse.c b/src/lj_parse.c

+ index 9e5976f..6785495 100644

+ --- a/src/lj_parse.c

+ +++ b/src/lj_parse.c

+ @@ -2696,7 +2696,8 @@ static int parse_stmt(LexState *ls)

+        lj_lex_next(ls);

+        parse_goto(ls);

+        break;

+ -    }  /* else: fallthrough */

+ +    }

+ +    /* fallthrough */

+    default:

+      parse_call_assign(ls);

+      break;

+ diff --git a/src/luajit.c b/src/luajit.c

+ index 9e15b26..0e18dc5 100644

+ --- a/src/luajit.c

+ +++ b/src/luajit.c

+ @@ -419,6 +419,7 @@ static int collectargs(char **argv, int *flags)

+        break;

+      case 'e':

+        *flags |= FLAGS_EXEC;

+ +      /* fallthrough */

+      case 'j':  /* LuaJIT extension */

+      case 'l':

+        *flags |= FLAGS_OPTION;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,32 @@ 

+ commit fddef924097f28c46a0a5b45483a6086b33cab81

+ Merge: 0bf46e1 03cd5aa

+ Author: Mike Pall <mike>

+ Date:   Mon Jan 29 13:28:53 2018 +0100

+ 

+     Merge branch 'master' into v2.1

+ 

+ From 03cd5aa749c1bc3bb4b7d4289236b6096cb3dc85 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Mon, 29 Jan 2018 13:25:51 +0100

+ Subject: [PATCH 33/72] Clear stack after print_jit_status() in CLI.

+ 

+ Suggested by Hydroque.

+ ---

+  src/luajit.c | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/src/luajit.c b/src/luajit.c

+ index 0e18dc5..9ede59c 100644

+ --- a/src/luajit.c

+ +++ b/src/luajit.c

+ @@ -151,6 +151,7 @@ static void print_jit_status(lua_State *L)

+      fputs(s, stdout);

+    }

+    putc('\n', stdout);

+ +  lua_settop(L, 0);  /* clear stack */

+  }

+  

+  static void createargtable(lua_State *L, char **argv, int argc, int argf)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,52 @@ 

+ From 046129dbdda5261c1b17469a2895a113d14c070a Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 27 Feb 2018 23:02:23 +0100

+ Subject: [PATCH 34/72] Fix rechaining of pseudo-resurrected string keys.

+ 

+ This is a serious bug. But extremely hard to reproduce, so it went

+ undetected for 8 years. One needs two resurrections with different

+ main nodes, which are both in a hash chain which gets relinked on

+ key insertion where the colliding node is in a non-main position. Phew.

+ 

+ Thanks to lbeiming.

+ ---

+  src/lj_tab.c | 23 +++++++++++++++++++++++

+  1 file changed, 23 insertions(+)

+ 

+ diff --git a/src/lj_tab.c b/src/lj_tab.c

+ index 50f447e..f2f3c0b 100644

+ --- a/src/lj_tab.c

+ +++ b/src/lj_tab.c

+ @@ -457,6 +457,29 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)

+  	  freenode->next = nn->next;

+  	  nn->next = n->next;

+  	  setmref(n->next, nn);

+ +	  /*

+ +	  ** Rechaining a resurrected string key creates a new dilemma:

+ +	  ** Another string key may have originally been resurrected via

+ +	  ** _any_ of the previous nodes as a chain anchor. Including

+ +	  ** a node that had to be moved, which makes them unreachable.

+ +	  ** It's not feasible to check for all previous nodes, so rechain

+ +	  ** any string key that's currently in a non-main positions.

+ +	  */

+ +	  while ((nn = nextnode(freenode))) {

+ +	    if (tvisstr(&nn->key) && !tvisnil(&nn->val)) {

+ +	      Node *mn = hashstr(t, strV(&nn->key));

+ +	      if (mn != freenode) {

+ +		freenode->next = nn->next;

+ +		nn->next = mn->next;

+ +		setmref(mn->next, nn);

+ +	      } else {

+ +		freenode = nn;

+ +	      }

+ +	    } else {

+ +	      freenode = nn;

+ +	    }

+ +	  }

+ +	  break;

+  	} else {

+  	  freenode = nn;

+  	}

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,50 @@ 

+ From fe651bf6e2b4d02b624be3c289378c08bab2fa9b Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 27 Feb 2018 23:22:40 +0100

+ Subject: [PATCH 35/72] DynASM/x86: Add BMI1 and BMI2 instructions.

+ 

+ Thanks to Peter Cawley.

+ ---

+  dynasm/dasm_x86.lua | 19 +++++++++++++++++++

+  1 file changed, 19 insertions(+)

+ 

+ diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua

+ index 4c031e2..c1d267a 100644

+ --- a/dynasm/dasm_x86.lua

+ +++ b/dynasm/dasm_x86.lua

+ @@ -955,6 +955,7 @@ end

+  --   "u"       Use VEX encoding, vvvv unused.

+  --   "v"/"V"   Use VEX encoding, vvvv from 1st/2nd operand (the operand is

+  --             removed from the list used by future characters).

+ +--   "w"       Use VEX encoding, vvvv from 3rd operand.

+  --   "L"       Force VEX.L

+  --

+  -- All of the following characters force a flush of the opcode:

+ @@ -1677,6 +1678,24 @@ local map_op = {

+    -- Intel ADX

+    adcx_2 =	"rmqd:660F38F6rM",

+    adox_2 =	"rmqd:F30F38F6rM",

+ +

+ +  -- BMI1

+ +  andn_3 =	"rrmqd:0F38VF2rM",

+ +  bextr_3 =	"rmrqd:0F38wF7rM",

+ +  blsi_2 =	"rmqd:0F38vF33m",

+ +  blsmsk_2 =	"rmqd:0F38vF32m",

+ +  blsr_2 =	"rmqd:0F38vF31m",

+ +  tzcnt_2 =	"rmqdw:F30FBCrM",

+ +

+ +  -- BMI2

+ +  bzhi_3 =	"rmrqd:0F38wF5rM",

+ +  mulx_3 =	"rrmqd:F20F38VF6rM",

+ +  pdep_3 =	"rrmqd:F20F38VF5rM",

+ +  pext_3 =	"rrmqd:F30F38VF5rM",

+ +  rorx_3 =	"rmSqd:F20F3AuF0rMS",

+ +  sarx_3 =	"rmrqd:F30F38wF7rM",

+ +  shrx_3 =	"rmrqd:F20F38wF7rM",

+ +  shlx_3 =	"rmrqd:660F38wF7rM",

+  }

+  

+  ------------------------------------------------------------------------------

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,55 @@ 

+ From f3cf0d6e15240098147437fed7bd436ff55fdf8c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 22 Apr 2018 13:14:28 +0200

+ Subject: [PATCH 36/72] Give expected results for negative non-base-10 numbers

+  in tonumber().

+ 

+ This was undefined in Lua 5.1, but it's defined in 5.2.

+ ---

+  src/lib_base.c | 27 ++++++++++++++++++---------

+  1 file changed, 18 insertions(+), 9 deletions(-)

+ 

+ diff --git a/src/lib_base.c b/src/lib_base.c

+ index 3a75787..d61e876 100644

+ --- a/src/lib_base.c

+ +++ b/src/lib_base.c

+ @@ -287,18 +287,27 @@ LJLIB_ASM(tonumber)		LJLIB_REC(.)

+    } else {

+      const char *p = strdata(lj_lib_checkstr(L, 1));

+      char *ep;

+ +    unsigned int neg = 0;

+      unsigned long ul;

+      if (base < 2 || base > 36)

+        lj_err_arg(L, 2, LJ_ERR_BASERNG);

+ -    ul = strtoul(p, &ep, base);

+ -    if (p != ep) {

+ -      while (lj_char_isspace((unsigned char)(*ep))) ep++;

+ -      if (*ep == '\0') {

+ -	if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))

+ -	  setintV(L->base-1-LJ_FR2, (int32_t)ul);

+ -	else

+ -	  setnumV(L->base-1-LJ_FR2, (lua_Number)ul);

+ -	return FFH_RES(1);

+ +    while (lj_char_isspace((unsigned char)(*p))) p++;

+ +    if (*p == '-') { p++; neg = 1; } else if (*p == '+') { p++; }

+ +    if (lj_char_isalnum((unsigned char)(*p))) {

+ +      ul = strtoul(p, &ep, base);

+ +      if (p != ep) {

+ +	while (lj_char_isspace((unsigned char)(*ep))) ep++;

+ +	if (*ep == '\0') {

+ +	  if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {

+ +	    if (neg) ul = -ul;

+ +	    setintV(L->base-1-LJ_FR2, (int32_t)ul);

+ +	  } else {

+ +	    lua_Number n = (lua_Number)ul;

+ +	    if (neg) n = -n;

+ +	    setnumV(L->base-1-LJ_FR2, n);

+ +	  }

+ +	  return FFH_RES(1);

+ +	}

+        }

+      }

+    }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,27 @@ 

+ From 02b521981a1ab919ff2cd4d9bcaee80baf77dce2 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 22 Apr 2018 13:27:25 +0200

+ Subject: [PATCH 37/72] FFI: Add tonumber() specialization for failed

+  conversions.

+ 

+ Contributed by Javier Guerra Giraldez.

+ ---

+  src/lj_crecord.c | 2 ++

+  1 file changed, 2 insertions(+)

+ 

+ diff --git a/src/lj_crecord.c b/src/lj_crecord.c

+ index 84fc49e..bc88d63 100644

+ --- a/src/lj_crecord.c

+ +++ b/src/lj_crecord.c

+ @@ -1661,6 +1661,8 @@ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)

+        d = ctype_get(cts, CTID_DOUBLE);

+      J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]);

+    } else {

+ +    /* Specialize to the ctype that couldn't be converted. */

+ +    argv2cdata(J, J->base[0], &rd->argv[0]);

+      J->base[0] = TREF_NIL;

+    }

+  }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,387 @@ 

+ From cf7a0540a3a9f80fc729211eb21d1e9b72acc89c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 25 Apr 2018 12:07:08 +0200

+ Subject: [PATCH 38/72] Bump copyright date to 2018.

+ 

+ ---

+  doc/bluequad-print.css     | 2 +-

+  doc/bluequad.css           | 2 +-

+  doc/changes.html           | 5 ++---

+  doc/contact.html           | 7 +++----

+  doc/ext_c_api.html         | 5 ++---

+  doc/ext_ffi.html           | 5 ++---

+  doc/ext_ffi_api.html       | 5 ++---

+  doc/ext_ffi_semantics.html | 5 ++---

+  doc/ext_ffi_tutorial.html  | 5 ++---

+  doc/ext_jit.html           | 5 ++---

+  doc/extensions.html        | 5 ++---

+  doc/faq.html               | 5 ++---

+  doc/install.html           | 5 ++---

+  doc/luajit.html            | 7 +++----

+  doc/running.html           | 5 ++---

+  doc/status.html            | 5 ++---

+  16 files changed, 32 insertions(+), 46 deletions(-)

+ 

+ diff --git a/doc/bluequad-print.css b/doc/bluequad-print.css

+ index 62e1c16..d5a3ea3 100644

+ --- a/doc/bluequad-print.css

+ +++ b/doc/bluequad-print.css

+ @@ -1,4 +1,4 @@

+ -/* Copyright (C) 2004-2017 Mike Pall.

+ +/* Copyright (C) 2004-2018 Mike Pall.

+   *

+   * You are welcome to use the general ideas of this design for your own sites.

+   * But please do not steal the stylesheet, the layout or the color scheme.

+ diff --git a/doc/bluequad.css b/doc/bluequad.css

+ index be2c4bf..cfc889a 100644

+ --- a/doc/bluequad.css

+ +++ b/doc/bluequad.css

+ @@ -1,4 +1,4 @@

+ -/* Copyright (C) 2004-2017 Mike Pall.

+ +/* Copyright (C) 2004-2018 Mike Pall.

+   *

+   * You are welcome to use the general ideas of this design for your own sites.

+   * But please do not steal the stylesheet, the layout or the color scheme.

+ diff --git a/doc/changes.html b/doc/changes.html

+ index 4a4d4fb..c1848e8 100644

+ --- a/doc/changes.html

+ +++ b/doc/changes.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>LuaJIT Change History</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -1010,7 +1009,7 @@ This is the initial non-public release of LuaJIT.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/contact.html b/doc/contact.html

+ index 5e07bde..54ddf74 100644

+ --- a/doc/contact.html

+ +++ b/doc/contact.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Contact</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -91,7 +90,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")

+  <h2>Copyright</h2>

+  <p>

+  All documentation is

+ -Copyright &copy; 2005-2017 Mike Pall.

+ +Copyright &copy; 2005-2018 Mike Pall.

+  </p>

+  

+  

+ @@ -99,7 +98,7 @@ Copyright &copy; 2005-2017 Mike Pall.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_c_api.html b/doc/ext_c_api.html

+ index 4bb8251..3825956 100644

+ --- a/doc/ext_c_api.html

+ +++ b/doc/ext_c_api.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Lua/C API Extensions</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -177,7 +176,7 @@ Also note that this mechanism is not without overhead.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_ffi.html b/doc/ext_ffi.html

+ index d48d77f..74ca294 100644

+ --- a/doc/ext_ffi.html

+ +++ b/doc/ext_ffi.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>FFI Library</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -320,7 +319,7 @@ without undue conversion penalties.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html

+ index 566897c..10f2d02 100644

+ --- a/doc/ext_ffi_api.html

+ +++ b/doc/ext_ffi_api.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>ffi.* API Functions</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -556,7 +555,7 @@ named <tt>i</tt>.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html

+ index ae3c037..218049d 100644

+ --- a/doc/ext_ffi_semantics.html

+ +++ b/doc/ext_ffi_semantics.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>FFI Semantics</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -1235,7 +1234,7 @@ compiled.</li>

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_ffi_tutorial.html b/doc/ext_ffi_tutorial.html

+ index 29cf549..cd455cf 100644

+ --- a/doc/ext_ffi_tutorial.html

+ +++ b/doc/ext_ffi_tutorial.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>FFI Tutorial</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -591,7 +590,7 @@ it to a local variable in the function scope is unnecessary.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/ext_jit.html b/doc/ext_jit.html

+ index 5017e3c..ce6dcd6 100644

+ --- a/doc/ext_jit.html

+ +++ b/doc/ext_jit.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>jit.* Library</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -189,7 +188,7 @@ if you want to know more.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/extensions.html b/doc/extensions.html

+ index 3d9e82b..fa412e0 100644

+ --- a/doc/extensions.html

+ +++ b/doc/extensions.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Extensions</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -398,7 +397,7 @@ lead to the termination of the process.</li>

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/faq.html b/doc/faq.html

+ index afeff94..9338be4 100644

+ --- a/doc/faq.html

+ +++ b/doc/faq.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Frequently Asked Questions (FAQ)</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -174,7 +173,7 @@ the development of certain features, if they are important to you.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/install.html b/doc/install.html

+ index 4bcc506..befffa7 100644

+ --- a/doc/install.html

+ +++ b/doc/install.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Installation</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -636,7 +635,7 @@ to me (the upstream) and not you (the package maintainer), anyway.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/luajit.html b/doc/luajit.html

+ index 0003008..d8f531d 100644

+ --- a/doc/luajit.html

+ +++ b/doc/luajit.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>LuaJIT</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -150,7 +149,7 @@ Lua is a powerful, dynamic and light-weight programming language.

+  It may be embedded or used as a general-purpose, stand-alone language.

+  </p>

+  <p>

+ -LuaJIT is Copyright &copy; 2005-2017 Mike Pall, released under the

+ +LuaJIT is Copyright &copy; 2005-2018 Mike Pall, released under the

+  <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT open source license</a>.

+  </p>

+  <p>

+ @@ -224,7 +223,7 @@ Please select a sub-topic in the navigation bar to learn more about LuaJIT.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/running.html b/doc/running.html

+ index 331c22d..08d7f71 100644

+ --- a/doc/running.html

+ +++ b/doc/running.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Running LuaJIT</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -296,7 +295,7 @@ Here are the parameters and their default settings:

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ diff --git a/doc/status.html b/doc/status.html

+ index aa8df93..ea61db1 100644

+ --- a/doc/status.html

+ +++ b/doc/status.html

+ @@ -3,8 +3,7 @@

+  <head>

+  <title>Status</title>

+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

+ -<meta name="Author" content="Mike Pall">

+ -<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">

+ +<meta name="Copyright" content="Copyright (C) 2005-2018">

+  <meta name="Language" content="en">

+  <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">

+  <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">

+ @@ -100,7 +99,7 @@ garbage collector.

+  </div>

+  <div id="foot">

+  <hr class="hide">

+ -Copyright &copy; 2005-2017 Mike Pall

+ +Copyright &copy; 2005-2018

+  <span class="noprint">

+  &middot;

+  <a href="contact.html">Contact</a>

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,52 @@ 

+ commit 362f034c1b91d52ea2cf971314ed4e0c24348bff

+ Merge: 260b9b4 f5d424a

+ Author: Mike Pall <mike>

+ Date:   Sun May 20 12:28:10 2018 +0200

+ 

+     Merge branch 'master' into v2.1

+ 

+ From f5d424afe8b9395f0df05aba905e0e1f6a2262b8 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 20 May 2018 12:25:36 +0200

+ Subject: [PATCH 39/72] FFI: Make FP to U64 conversions match JIT backend

+  behavior.

+ 

+ ---

+  src/lj_obj.h | 18 +++++++++++++-----

+  1 file changed, 13 insertions(+), 5 deletions(-)

+ 

+ diff --git a/src/lj_obj.h b/src/lj_obj.h

+ index e70b003..2ee526c 100644

+ --- a/src/lj_obj.h

+ +++ b/src/lj_obj.h

+ @@ -816,14 +816,22 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)

+  

+  #define lj_num2int(n)   ((int32_t)(n))

+  

+ +/*

+ +** This must match the JIT backend behavior. In particular for archs

+ +** that don't have a common hardware instruction for this conversion.

+ +** Note that signed FP to unsigned int conversions have an undefined

+ +** result and should never be relied upon in portable FFI code.

+ +** See also: C99 or C11 standard, 6.3.1.4, footnote of (1).

+ +*/

+  static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)

+  {

+ -#ifdef _MSC_VER

+ -  if (n >= 9223372036854775808.0)  /* They think it's a feature. */

+ -    return (uint64_t)(int64_t)(n - 18446744073709551616.0);

+ -  else

+ +#if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS

+ +  int64_t i = (int64_t)n;

+ +  if (i < 0) i = (int64_t)(n - 18446744073709551616.0);

+ +  return (uint64_t)i;

+ +#else

+ +  return (uint64_t)n;

+  #endif

+ -    return (uint64_t)n;

+  }

+  

+  static LJ_AINLINE int32_t numberVint(cTValue *o)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,33 @@ 

+ From fb5e522fbc0750c838ef6a926b11c5d870826183 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 20 May 2018 12:40:33 +0200

+ Subject: [PATCH 40/72] x86/x64: Check for jcc when using xor r,r in

+  emit_loadi().

+ 

+ Thanks to Peter Cawley.

+ ---

+  src/lj_emit_x86.h | 6 ++++--

+  1 file changed, 4 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/lj_emit_x86.h b/src/lj_emit_x86.h

+ index bcceb93..9c371a9 100644

+ --- a/src/lj_emit_x86.h

+ +++ b/src/lj_emit_x86.h

+ @@ -268,10 +268,12 @@ static void emit_movmroi(ASMState *as, Reg base, int32_t ofs, int32_t i)

+  /* mov r, i / xor r, r */

+  static void emit_loadi(ASMState *as, Reg r, int32_t i)

+  {

+ -  /* XOR r,r is shorter, but modifies the flags. This is bad for HIOP. */

+ +  /* XOR r,r is shorter, but modifies the flags. This is bad for HIOP/jcc. */

+    if (i == 0 && !(LJ_32 && (IR(as->curins)->o == IR_HIOP ||

+  			    (as->curins+1 < as->T->nins &&

+ -			     IR(as->curins+1)->o == IR_HIOP)))) {

+ +			     IR(as->curins+1)->o == IR_HIOP))) &&

+ +		!((*as->mcp == 0x0f && (as->mcp[1] & 0xf0) == XI_JCCn) ||

+ +		  (*as->mcp & 0xf0) == XI_JCCs)) {

+      emit_rr(as, XO_ARITH(XOg_XOR), r, r);

+    } else {

+      MCode *p = as->mcp;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,33 @@ 

+ commit d36afcfea57c29fb51060c24679f3b2c07806545

+ Merge: b708297 b025b01

+ Author: Mike Pall <mike>

+ Date:   Tue Jun 5 11:39:10 2018 +0200

+ 

+     Merge branch 'master' into v2.1

+ 

+ From b025b01c5b9d23f6218c7d72b7aafa3f1ab1e08a Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 5 Jun 2018 11:36:18 +0200

+ Subject: [PATCH 41/72] PPC/NetBSD: Fix endianess check.

+ 

+ Thanks to he32 and daurnimator.

+ ---

+  src/lj_arch.h | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_arch.h b/src/lj_arch.h

+ index e04c4ee..5f7e445 100644

+ --- a/src/lj_arch.h

+ +++ b/src/lj_arch.h

+ @@ -339,7 +339,7 @@

+  #error "No support for ILP32 model on ARM64"

+  #endif

+  #elif LJ_TARGET_PPC

+ -#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE

+ +#if !LJ_ARCH_PPC64 && (defined(_LITTLE_ENDIAN) && (!defined(_BYTE_ORDER) || (_BYTE_ORDER == _LITTLE_ENDIAN)))

+  #error "No support for little-endian PPC32"

+  #endif

+  #if LJ_ARCH_PPC64

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,91 @@ 

+ From cc299958bb412f229844e53473a035c280544ec3 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 5 Jun 2018 12:23:13 +0200

+ Subject: [PATCH 42/72] DynASM/x86: Add FMA3 instructions.

+ 

+ Thanks to Alexander Nasonov.

+ ---

+  dynasm/dasm_x86.lua | 67 +++++++++++++++++++++++++++++++++++++++++++++

+  1 file changed, 67 insertions(+)

+ 

+ diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua

+ index c1d267a..73502f6 100644

+ --- a/dynasm/dasm_x86.lua

+ +++ b/dynasm/dasm_x86.lua

+ @@ -1696,6 +1696,73 @@ local map_op = {

+    sarx_3 =	"rmrqd:F30F38wF7rM",

+    shrx_3 =	"rmrqd:F20F38wF7rM",

+    shlx_3 =	"rmrqd:660F38wF7rM",

+ +

+ +  -- FMA3

+ +  vfmaddsub132pd_3 = "rrmoy:660F38VX96rM",

+ +  vfmaddsub132ps_3 = "rrmoy:660F38V96rM",

+ +  vfmaddsub213pd_3 = "rrmoy:660F38VXA6rM",

+ +  vfmaddsub213ps_3 = "rrmoy:660F38VA6rM",

+ +  vfmaddsub231pd_3 = "rrmoy:660F38VXB6rM",

+ +  vfmaddsub231ps_3 = "rrmoy:660F38VB6rM",

+ +

+ +  vfmsubadd132pd_3 = "rrmoy:660F38VX97rM",

+ +  vfmsubadd132ps_3 = "rrmoy:660F38V97rM",

+ +  vfmsubadd213pd_3 = "rrmoy:660F38VXA7rM",

+ +  vfmsubadd213ps_3 = "rrmoy:660F38VA7rM",

+ +  vfmsubadd231pd_3 = "rrmoy:660F38VXB7rM",

+ +  vfmsubadd231ps_3 = "rrmoy:660F38VB7rM",

+ +

+ +  vfmadd132pd_3 = "rrmoy:660F38VX98rM",

+ +  vfmadd132ps_3 = "rrmoy:660F38V98rM",

+ +  vfmadd132sd_3 = "rrro:660F38VX99rM|rrx/ooq:",

+ +  vfmadd132ss_3 = "rrro:660F38V99rM|rrx/ood:",

+ +  vfmadd213pd_3 = "rrmoy:660F38VXA8rM",

+ +  vfmadd213ps_3 = "rrmoy:660F38VA8rM",

+ +  vfmadd213sd_3 = "rrro:660F38VXA9rM|rrx/ooq:",

+ +  vfmadd213ss_3 = "rrro:660F38VA9rM|rrx/ood:",

+ +  vfmadd231pd_3 = "rrmoy:660F38VXB8rM",

+ +  vfmadd231ps_3 = "rrmoy:660F38VB8rM",

+ +  vfmadd231sd_3 = "rrro:660F38VXB9rM|rrx/ooq:",

+ +  vfmadd231ss_3 = "rrro:660F38VB9rM|rrx/ood:",

+ +

+ +  vfmsub132pd_3 = "rrmoy:660F38VX9ArM",

+ +  vfmsub132ps_3 = "rrmoy:660F38V9ArM",

+ +  vfmsub132sd_3 = "rrro:660F38VX9BrM|rrx/ooq:",

+ +  vfmsub132ss_3 = "rrro:660F38V9BrM|rrx/ood:",

+ +  vfmsub213pd_3 = "rrmoy:660F38VXAArM",

+ +  vfmsub213ps_3 = "rrmoy:660F38VAArM",

+ +  vfmsub213sd_3 = "rrro:660F38VXABrM|rrx/ooq:",

+ +  vfmsub213ss_3 = "rrro:660F38VABrM|rrx/ood:",

+ +  vfmsub231pd_3 = "rrmoy:660F38VXBArM",

+ +  vfmsub231ps_3 = "rrmoy:660F38VBArM",

+ +  vfmsub231sd_3 = "rrro:660F38VXBBrM|rrx/ooq:",

+ +  vfmsub231ss_3 = "rrro:660F38VBBrM|rrx/ood:",

+ +

+ +  vfnmadd132pd_3 = "rrmoy:660F38VX9CrM",

+ +  vfnmadd132ps_3 = "rrmoy:660F38V9CrM",

+ +  vfnmadd132sd_3 = "rrro:660F38VX9DrM|rrx/ooq:",

+ +  vfnmadd132ss_3 = "rrro:660F38V9DrM|rrx/ood:",

+ +  vfnmadd213pd_3 = "rrmoy:660F38VXACrM",

+ +  vfnmadd213ps_3 = "rrmoy:660F38VACrM",

+ +  vfnmadd213sd_3 = "rrro:660F38VXADrM|rrx/ooq:",

+ +  vfnmadd213ss_3 = "rrro:660F38VADrM|rrx/ood:",

+ +  vfnmadd231pd_3 = "rrmoy:660F38VXBCrM",

+ +  vfnmadd231ps_3 = "rrmoy:660F38VBCrM",

+ +  vfnmadd231sd_3 = "rrro:660F38VXBDrM|rrx/ooq:",

+ +  vfnmadd231ss_3 = "rrro:660F38VBDrM|rrx/ood:",

+ +

+ +  vfnmsub132pd_3 = "rrmoy:660F38VX9ErM",

+ +  vfnmsub132ps_3 = "rrmoy:660F38V9ErM",

+ +  vfnmsub132sd_3 = "rrro:660F38VX9FrM|rrx/ooq:",

+ +  vfnmsub132ss_3 = "rrro:660F38V9FrM|rrx/ood:",

+ +  vfnmsub213pd_3 = "rrmoy:660F38VXAErM",

+ +  vfnmsub213ps_3 = "rrmoy:660F38VAErM",

+ +  vfnmsub213sd_3 = "rrro:660F38VXAFrM|rrx/ooq:",

+ +  vfnmsub213ss_3 = "rrro:660F38VAFrM|rrx/ood:",

+ +  vfnmsub231pd_3 = "rrmoy:660F38VXBErM",

+ +  vfnmsub231ps_3 = "rrmoy:660F38VBErM",

+ +  vfnmsub231sd_3 = "rrro:660F38VXBFrM|rrx/ooq:",

+ +  vfnmsub231ss_3 = "rrro:660F38VBFrM|rrx/ood:",

+  }

+  

+  ------------------------------------------------------------------------------

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,69 @@ 

+ From 55f70823242aa4e6acc248bde5cf8194ba1b27e3 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 5 Jun 2018 12:23:29 +0200

+ Subject: [PATCH 43/72] x86: Disassemble FMA3 instructions.

+ 

+ Thanks to Alexander Nasonov.

+ ---

+  src/jit/dis_x86.lua | 24 +++++++++++++++++++++++-

+  1 file changed, 23 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua

+ index 4371233..3a68c93 100644

+ --- a/src/jit/dis_x86.lua

+ +++ b/src/jit/dis_x86.lua

+ @@ -239,6 +239,24 @@ nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",

+  --8x

+  [0x8c] = "||pmaskmovXrvVSm",

+  [0x8e] = "||pmaskmovVSmXvr",

+ +--9x

+ +[0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm",

+ +[0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm",

+ +[0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm",

+ +[0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm",

+ +[0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm",

+ +--Ax

+ +[0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm",

+ +[0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm",

+ +[0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm",

+ +[0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm",

+ +[0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm",

+ +--Bx

+ +[0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm",

+ +[0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm",

+ +[0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm",

+ +[0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm",

+ +[0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm",

+  --Dx

+  [0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm",

+  [0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm",

+ @@ -483,7 +501,7 @@ local function putpat(ctx, name, pat)

+    local operands, regs, sz, mode, sp, rm, sc, rx, sdisp

+    local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl

+  

+ -  -- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz

+ +  -- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz

+    for p in gmatch(pat, ".") do

+      local x = nil

+      if p == "V" or p == "U" then

+ @@ -506,6 +524,9 @@ local function putpat(ctx, name, pat)

+        sz = ctx.o16 and "X" or "M"; ctx.o16 = false

+        if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end

+        regs = map_regs[sz]

+ +    elseif p == "H" then

+ +      name = name..(ctx.rexw and "d" or "s")

+ +      ctx.rexw = false

+      elseif p == "S" then

+        name = name..lower(sz)

+      elseif p == "s" then

+ @@ -735,6 +756,7 @@ map_act = {

+    V = putpat, U = putpat, T = putpat,

+    M = putpat, X = putpat, P = putpat,

+    F = putpat, G = putpat, Y = putpat,

+ +  H = putpat,

+  

+    -- Collect prefixes.

+    [":"] = function(ctx, name, pat)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,49 @@ 

+ From a5a89ab586a3b5bb4f266949bbf3dc2b140e2374 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 5 Jun 2018 12:23:56 +0200

+ Subject: [PATCH 44/72] From Lua 5.3: assert() accepts any type of error

+  object.

+ 

+ ---

+  doc/extensions.html |  1 +

+  src/lib_base.c      | 10 +++++-----

+  2 files changed, 6 insertions(+), 5 deletions(-)

+ 

+ diff --git a/doc/extensions.html b/doc/extensions.html

+ index 55c4b70..7379041 100644

+ --- a/doc/extensions.html

+ +++ b/doc/extensions.html

+ @@ -373,6 +373,7 @@ LuaJIT supports some extensions from Lua&nbsp;5.3:

+  <li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>

+  <li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>

+  <li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li>

+ +<li><tt>assert()</tt> accepts any type of error object.</li>

+  <li><tt>table.move(a1, f, e, t [,a2])</tt>.</li>

+  <li><tt>coroutine.isyieldable()</tt>.</li>

+  <li>Lua/C API extensions:

+ diff --git a/src/lib_base.c b/src/lib_base.c

+ index d61e876..1cd8305 100644

+ --- a/src/lib_base.c

+ +++ b/src/lib_base.c

+ @@ -42,13 +42,13 @@

+  

+  LJLIB_ASM(assert)		LJLIB_REC(.)

+  {

+ -  GCstr *s;

+    lj_lib_checkany(L, 1);

+ -  s = lj_lib_optstr(L, 2);

+ -  if (s)

+ -    lj_err_callermsg(L, strdata(s));

+ -  else

+ +  if (L->top == L->base+1)

+      lj_err_caller(L, LJ_ERR_ASSERT);

+ +  else if (tvisstr(L->base+1) || tvisnumber(L->base+1))

+ +    lj_err_callermsg(L, strdata(lj_lib_checkstr(L, 2)));

+ +  else

+ +    lj_err_run(L);

+    return FFH_UNREACHABLE;

+  }

+  

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,359 @@ 

+ From c3c54ce1aef782823936808a75460e6b53aada2c Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Tue, 5 Jun 2018 17:03:08 +0200

+ Subject: [PATCH 45/72] Windows: Add UWP support, part 1.

+ 

+ Contributed by Ben Pye.

+ ---

+  doc/ext_ffi_api.html |  2 ++

+  src/lib_ffi.c        |  3 +++

+  src/lib_io.c         |  4 ++--

+  src/lib_package.c    | 24 +++++++++++++++++++++++-

+  src/lj_alloc.c       |  6 +++---

+  src/lj_arch.h        | 19 +++++++++++++++++++

+  src/lj_ccallback.c   |  4 ++--

+  src/lj_clib.c        | 20 ++++++++++++++++----

+  src/lj_mcode.c       |  8 ++++----

+  src/lj_profile.c     |  8 ++++----

+  10 files changed, 78 insertions(+), 20 deletions(-)

+ 

+ diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html

+ index 25cc974..54ff0ce 100644

+ --- a/doc/ext_ffi_api.html

+ +++ b/doc/ext_ffi_api.html

+ @@ -468,6 +468,8 @@ otherwise. The following parameters are currently defined:

+  <tr class="odd">

+  <td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>

+  <tr class="even">

+ +<td class="abiparam">uwp</td><td class="abidesc">Universal Windows Platform</td></tr>

+ +<tr class="odd">

+  <td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>

+  </table>

+  

+ diff --git a/src/lib_ffi.c b/src/lib_ffi.c

+ index 199cfc9..8032411 100644

+ --- a/src/lib_ffi.c

+ +++ b/src/lib_ffi.c

+ @@ -746,6 +746,9 @@ LJLIB_CF(ffi_abi)	LJLIB_REC(.)

+  #endif

+  #if LJ_ABI_WIN

+    case H_(4ab624a8,4ab624a8): b = 1; break;  /* win */

+ +#endif

+ +#if LJ_TARGET_UWP

+ +  case H_(a40f0bcb,a40f0bcb): b = 1; break;  /* uwp */

+  #endif

+    case H_(3af93066,1f001464): b = 1; break;  /* le/be */

+  #if LJ_GC64

+ diff --git a/src/lib_io.c b/src/lib_io.c

+ index 9763ed4..73fd932 100644

+ --- a/src/lib_io.c

+ +++ b/src/lib_io.c

+ @@ -99,7 +99,7 @@ static int io_file_close(lua_State *L, IOFileUD *iof)

+      int stat = -1;

+  #if LJ_TARGET_POSIX

+      stat = pclose(iof->fp);

+ -#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE

+ +#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP

+      stat = _pclose(iof->fp);

+  #else

+      lua_assert(0);

+ @@ -406,7 +406,7 @@ LJLIB_CF(io_open)

+  

+  LJLIB_CF(io_popen)

+  {

+ -#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE)

+ +#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP)

+    const char *fname = strdata(lj_lib_checkstr(L, 1));

+    GCstr *s = lj_lib_optstr(L, 2);

+    const char *mode = s ? strdata(s) : "r";

+ diff --git a/src/lib_package.c b/src/lib_package.c

+ index 6fac43e..bedd6d7 100644

+ --- a/src/lib_package.c

+ +++ b/src/lib_package.c

+ @@ -76,6 +76,20 @@ static const char *ll_bcsym(void *lib, const char *sym)

+  BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);

+  #endif

+  

+ +#if LJ_TARGET_UWP

+ +void *LJ_WIN_LOADLIBA(const char *path)

+ +{

+ +  DWORD err = GetLastError();

+ +  wchar_t wpath[256];

+ +  HANDLE lib = NULL;

+ +  if (MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, 256) > 0) {

+ +    lib = LoadPackagedLibrary(wpath, 0);

+ +  }

+ +  SetLastError(err);

+ +  return lib;

+ +}

+ +#endif

+ +

+  #undef setprogdir

+  

+  static void setprogdir(lua_State *L)

+ @@ -119,7 +133,7 @@ static void ll_unloadlib(void *lib)

+  

+  static void *ll_load(lua_State *L, const char *path, int gl)

+  {

+ -  HINSTANCE lib = LoadLibraryExA(path, NULL, 0);

+ +  HINSTANCE lib = LJ_WIN_LOADLIBA(path);

+    if (lib == NULL) pusherror(L);

+    UNUSED(gl);

+    return lib;

+ @@ -132,17 +146,25 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)

+    return f;

+  }

+  

+ +#if LJ_TARGET_UWP

+ +EXTERN_C IMAGE_DOS_HEADER __ImageBase;

+ +#endif

+ +

+  static const char *ll_bcsym(void *lib, const char *sym)

+  {

+    if (lib) {

+      return (const char *)GetProcAddress((HINSTANCE)lib, sym);

+    } else {

+ +#if LJ_TARGET_UWP

+ +    return (const char *)GetProcAddress((HINSTANCE)&__ImageBase, sym);

+ +#else

+      HINSTANCE h = GetModuleHandleA(NULL);

+      const char *p = (const char *)GetProcAddress(h, sym);

+      if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,

+  					(const char *)ll_bcsym, &h))

+        p = (const char *)GetProcAddress(h, sym);

+      return p;

+ +#endif

+    }

+  }

+  

+ diff --git a/src/lj_alloc.c b/src/lj_alloc.c

+ index 9fc761c..f3b6a54 100644

+ --- a/src/lj_alloc.c

+ +++ b/src/lj_alloc.c

+ @@ -167,7 +167,7 @@ static void *DIRECT_MMAP(size_t size)

+  static void *CALL_MMAP(size_t size)

+  {

+    DWORD olderr = GetLastError();

+ -  void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

+ +  void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

+    SetLastError(olderr);

+    return ptr ? ptr : MFAIL;

+  }

+ @@ -176,8 +176,8 @@ static void *CALL_MMAP(size_t size)

+  static void *DIRECT_MMAP(size_t size)

+  {

+    DWORD olderr = GetLastError();

+ -  void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,

+ -			   PAGE_READWRITE);

+ +  void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,

+ +			    PAGE_READWRITE);

+    SetLastError(olderr);

+    return ptr ? ptr : MFAIL;

+  }

+ diff --git a/src/lj_arch.h b/src/lj_arch.h

+ index e796912..31a1159 100644

+ --- a/src/lj_arch.h

+ +++ b/src/lj_arch.h

+ @@ -135,6 +135,13 @@

+  #define LJ_TARGET_GC64		1

+  #endif

+  

+ +#ifdef _UWP

+ +#define LJ_TARGET_UWP		1

+ +#if LUAJIT_TARGET == LUAJIT_ARCH_X64

+ +#define LJ_TARGET_GC64		1

+ +#endif

+ +#endif

+ +

+  #define LJ_NUMMODE_SINGLE	0	/* Single-number mode only. */

+  #define LJ_NUMMODE_SINGLE_DUAL	1	/* Default to single-number mode. */

+  #define LJ_NUMMODE_DUAL		2	/* Dual-number mode only. */

+ @@ -570,6 +577,18 @@

+  #define LJ_NO_UNWIND		1

+  #endif

+  

+ +#if LJ_TARGET_WINDOWS

+ +#if LJ_TARGET_UWP

+ +#define LJ_WIN_VALLOC	VirtualAllocFromApp

+ +#define LJ_WIN_VPROTECT	VirtualProtectFromApp

+ +extern void *LJ_WIN_LOADLIBA(const char *path);

+ +#else

+ +#define LJ_WIN_VALLOC	VirtualAlloc

+ +#define LJ_WIN_VPROTECT	VirtualProtect

+ +#define LJ_WIN_LOADLIBA(path)	LoadLibraryExA((path), NULL, 0)

+ +#endif

+ +#endif

+ +

+  /* Compatibility with Lua 5.1 vs. 5.2. */

+  #ifdef LUAJIT_ENABLE_LUA52COMPAT

+  #define LJ_52			1

+ diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c

+ index 03494a7..412dbf8 100644

+ --- a/src/lj_ccallback.c

+ +++ b/src/lj_ccallback.c

+ @@ -267,7 +267,7 @@ static void callback_mcode_new(CTState *cts)

+    if (CALLBACK_MAX_SLOT == 0)

+      lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);

+  #if LJ_TARGET_WINDOWS

+ -  p = VirtualAlloc(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

+ +  p = LJ_WIN_VALLOC(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

+    if (!p)

+      lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);

+  #elif LJ_TARGET_POSIX

+ @@ -285,7 +285,7 @@ static void callback_mcode_new(CTState *cts)

+  #if LJ_TARGET_WINDOWS

+    {

+      DWORD oprot;

+ -    VirtualProtect(p, sz, PAGE_EXECUTE_READ, &oprot);

+ +    LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot);

+    }

+  #elif LJ_TARGET_POSIX

+    mprotect(p, sz, (PROT_READ|PROT_EXEC));

+ diff --git a/src/lj_clib.c b/src/lj_clib.c

+ index 6142659..f016b06 100644

+ --- a/src/lj_clib.c

+ +++ b/src/lj_clib.c

+ @@ -158,11 +158,13 @@ BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);

+  /* Default libraries. */

+  enum {

+    CLIB_HANDLE_EXE,

+ +#if !LJ_TARGET_UWP

+    CLIB_HANDLE_DLL,

+    CLIB_HANDLE_CRT,

+    CLIB_HANDLE_KERNEL32,

+    CLIB_HANDLE_USER32,

+    CLIB_HANDLE_GDI32,

+ +#endif

+    CLIB_HANDLE_MAX

+  };

+  

+ @@ -208,7 +210,7 @@ static const char *clib_extname(lua_State *L, const char *name)

+  static void *clib_loadlib(lua_State *L, const char *name, int global)

+  {

+    DWORD oldwerr = GetLastError();

+ -  void *h = (void *)LoadLibraryExA(clib_extname(L, name), NULL, 0);

+ +  void *h = LJ_WIN_LOADLIBA(clib_extname(L, name));

+    if (!h) clib_error(L, "cannot load module " LUA_QS ": %s", name);

+    SetLastError(oldwerr);

+    UNUSED(global);

+ @@ -218,6 +220,7 @@ static void *clib_loadlib(lua_State *L, const char *name, int global)

+  static void clib_unloadlib(CLibrary *cl)

+  {

+    if (cl->handle == CLIB_DEFHANDLE) {

+ +#if !LJ_TARGET_UWP

+      MSize i;

+      for (i = CLIB_HANDLE_KERNEL32; i < CLIB_HANDLE_MAX; i++) {

+        void *h = clib_def_handle[i];

+ @@ -226,11 +229,16 @@ static void clib_unloadlib(CLibrary *cl)

+  	FreeLibrary((HINSTANCE)h);

+        }

+      }

+ +#endif

+    } else if (cl->handle) {

+      FreeLibrary((HINSTANCE)cl->handle);

+    }

+  }

+  

+ +#if LJ_TARGET_UWP

+ +EXTERN_C IMAGE_DOS_HEADER __ImageBase;

+ +#endif

+ +

+  static void *clib_getsym(CLibrary *cl, const char *name)

+  {

+    void *p = NULL;

+ @@ -239,6 +247,9 @@ static void *clib_getsym(CLibrary *cl, const char *name)

+      for (i = 0; i < CLIB_HANDLE_MAX; i++) {

+        HINSTANCE h = (HINSTANCE)clib_def_handle[i];

+        if (!(void *)h) {  /* Resolve default library handles (once). */

+ +#if LJ_TARGET_UWP

+ +	h = (HINSTANCE)&__ImageBase;

+ +#else

+  	switch (i) {

+  	case CLIB_HANDLE_EXE: GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, &h); break;

+  	case CLIB_HANDLE_DLL:

+ @@ -249,11 +260,12 @@ static void *clib_getsym(CLibrary *cl, const char *name)

+  	  GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,

+  			     (const char *)&_fmode, &h);

+  	  break;

+ -	case CLIB_HANDLE_KERNEL32: h = LoadLibraryExA("kernel32.dll", NULL, 0); break;

+ -	case CLIB_HANDLE_USER32: h = LoadLibraryExA("user32.dll", NULL, 0); break;

+ -	case CLIB_HANDLE_GDI32: h = LoadLibraryExA("gdi32.dll", NULL, 0); break;

+ +	case CLIB_HANDLE_KERNEL32: h = LJ_WIN_LOADLIBA("kernel32.dll"); break;

+ +	case CLIB_HANDLE_USER32: h = LJ_WIN_LOADLIBA("user32.dll"); break;

+ +	case CLIB_HANDLE_GDI32: h = LJ_WIN_LOADLIBA("gdi32.dll"); break;

+  	}

+  	if (!h) continue;

+ +#endif

+  	clib_def_handle[i] = (void *)h;

+        }

+        p = (void *)GetProcAddress(h, name);

+ diff --git a/src/lj_mcode.c b/src/lj_mcode.c

+ index e46e3ef..64b0ca9 100644

+ --- a/src/lj_mcode.c

+ +++ b/src/lj_mcode.c

+ @@ -66,8 +66,8 @@ void lj_mcode_sync(void *start, void *end)

+  

+  static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, DWORD prot)

+  {

+ -  void *p = VirtualAlloc((void *)hint, sz,

+ -			 MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot);

+ +  void *p = LJ_WIN_VALLOC((void *)hint, sz,

+ +			  MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot);

+    if (!p && !hint)

+      lj_trace_err(J, LJ_TRERR_MCODEAL);

+    return p;

+ @@ -82,7 +82,7 @@ static void mcode_free(jit_State *J, void *p, size_t sz)

+  static int mcode_setprot(void *p, size_t sz, DWORD prot)

+  {

+    DWORD oprot;

+ -  return !VirtualProtect(p, sz, prot, &oprot);

+ +  return !LJ_WIN_VPROTECT(p, sz, prot, &oprot);

+  }

+  

+  #elif LJ_TARGET_POSIX

+ @@ -255,7 +255,7 @@ static void *mcode_alloc(jit_State *J, size_t sz)

+  /* All memory addresses are reachable by relative jumps. */

+  static void *mcode_alloc(jit_State *J, size_t sz)

+  {

+ -#ifdef __OpenBSD__

+ +#if defined(__OpenBSD__) || LJ_TARGET_UWP

+    /* Allow better executable memory allocation for OpenBSD W^X mode. */

+    void *p = mcode_alloc_at(J, 0, sz, MCPROT_RUN);

+    if (p && mcode_setprot(p, sz, MCPROT_GEN)) {

+ diff --git a/src/lj_profile.c b/src/lj_profile.c

+ index 116998e..3223697 100644

+ --- a/src/lj_profile.c

+ +++ b/src/lj_profile.c

+ @@ -247,7 +247,7 @@ static DWORD WINAPI profile_thread(void *psx)

+  {

+    ProfileState *ps = (ProfileState *)psx;

+    int interval = ps->interval;

+ -#if LJ_TARGET_WINDOWS

+ +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP

+    ps->wmm_tbp(interval);

+  #endif

+    while (1) {

+ @@ -255,7 +255,7 @@ static DWORD WINAPI profile_thread(void *psx)

+      if (ps->abort) break;

+      profile_trigger(ps);

+    }

+ -#if LJ_TARGET_WINDOWS

+ +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP

+    ps->wmm_tep(interval);

+  #endif

+    return 0;

+ @@ -264,9 +264,9 @@ static DWORD WINAPI profile_thread(void *psx)

+  /* Start profiling timer thread. */

+  static void profile_timer_start(ProfileState *ps)

+  {

+ -#if LJ_TARGET_WINDOWS

+ +#if LJ_TARGET_WINDOWS && !LJ_TARGET_UWP

+    if (!ps->wmm) {  /* Load WinMM library on-demand. */

+ -    ps->wmm = LoadLibraryExA("winmm.dll", NULL, 0);

+ +    ps->wmm = LJ_WIN_LOADLIBA("winmm.dll");

+      if (ps->wmm) {

+        ps->wmm_tbp = (WMM_TPFUNC)GetProcAddress(ps->wmm, "timeBeginPeriod");

+        ps->wmm_tep = (WMM_TPFUNC)GetProcAddress(ps->wmm, "timeEndPeriod");

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From c785131ca5a6d24adc519e5e0bf1b69b671d912f Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 24 Jun 2018 13:18:03 +0200

+ Subject: [PATCH 46/72] ARM64: Fix write barrier in BC_USETS.

+ 

+ Contributed by Javier Guerra Giraldez.

+ ---

+  src/vm_arm64.dasc | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc

+ index c55794a..fb226e3 100644

+ --- a/src/vm_arm64.dasc

+ +++ b/src/vm_arm64.dasc

+ @@ -2780,7 +2780,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)

+      |2:  // Check if string is white and ensure upvalue is closed.

+      |  ldrb TMP0w, UPVAL:CARG1->closed

+      |    tst TMP1w, #LJ_GC_WHITES	// iswhite(str)

+ -    |  ccmp TMP0w, #0, #0, ne

+ +    |  ccmp TMP0w, #0, #4, ne

+      |  beq <1

+      |  // Crossed a write barrier. Move the barrier forward.

+      |  mov CARG1, GL

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,238 @@ 

+ From 9da06535092d6d9dec442641a26c64bce5574322 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 24 Jun 2018 14:08:59 +0200

+ Subject: [PATCH 47/72] ARM64: Fix exit stub patching.

+ 

+ Contributed by Javier Guerra Giraldez.

+ ---

+  src/lj_asm_arm64.h    | 64 +++++++++++++++++++++++++------------------

+  src/lj_emit_arm64.h   | 18 ++++++------

+  src/lj_target_arm64.h |  7 +++--

+  3 files changed, 51 insertions(+), 38 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index cbb186d..baafa21 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -56,11 +56,11 @@ static void asm_exitstub_setup(ASMState *as, ExitNo nexits)

+      asm_mclimit(as);

+    /* 1: str lr,[sp]; bl ->vm_exit_handler; movz w0,traceno; bl <1; bl <1; ... */

+    for (i = nexits-1; (int32_t)i >= 0; i--)

+ -    *--mxp = A64I_LE(A64I_BL|((-3-i)&0x03ffffffu));

+ -  *--mxp = A64I_LE(A64I_MOVZw|A64F_U16(as->T->traceno));

+ +    *--mxp = A64I_LE(A64I_BL | A64F_S26(-3-i));

+ +  *--mxp = A64I_LE(A64I_MOVZw | A64F_U16(as->T->traceno));

+    mxp--;

+ -  *mxp = A64I_LE(A64I_BL|(((MCode *)(void *)lj_vm_exit_handler-mxp)&0x03ffffffu));

+ -  *--mxp = A64I_LE(A64I_STRx|A64F_D(RID_LR)|A64F_N(RID_SP));

+ +  *mxp = A64I_LE(A64I_BL | A64F_S26(((MCode *)(void *)lj_vm_exit_handler-mxp)));

+ +  *--mxp = A64I_LE(A64I_STRx | A64F_D(RID_LR) | A64F_N(RID_SP));

+    as->mctop = mxp;

+  }

+  

+ @@ -77,7 +77,7 @@ static void asm_guardcc(ASMState *as, A64CC cc)

+    MCode *p = as->mcp;

+    if (LJ_UNLIKELY(p == as->invmcp)) {

+      as->loopinv = 1;

+ -    *p = A64I_B | ((target-p) & 0x03ffffffu);

+ +    *p = A64I_B | A64F_S26(target-p);

+      emit_cond_branch(as, cc^1, p-1);

+      return;

+    }

+ @@ -91,7 +91,7 @@ static void asm_guardtnb(ASMState *as, A64Ins ai, Reg r, uint32_t bit)

+    MCode *p = as->mcp;

+    if (LJ_UNLIKELY(p == as->invmcp)) {

+      as->loopinv = 1;

+ -    *p = A64I_B | ((target-p) & 0x03ffffffu);

+ +    *p = A64I_B | A64F_S26(target-p);

+      emit_tnb(as, ai^0x01000000u, r, bit, p-1);

+      return;

+    }

+ @@ -105,7 +105,7 @@ static void asm_guardcnb(ASMState *as, A64Ins ai, Reg r)

+    MCode *p = as->mcp;

+    if (LJ_UNLIKELY(p == as->invmcp)) {

+      as->loopinv = 1;

+ -    *p = A64I_B | ((target-p) & 0x03ffffffu);

+ +    *p = A64I_B | A64F_S26(target-p);

+      emit_cnb(as, ai^0x01000000u, r, p-1);

+      return;

+    }

+ @@ -1850,7 +1850,7 @@ static void asm_loop_fixup(ASMState *as)

+      p[-2] |= ((uint32_t)delta & mask) << 5;

+    } else {

+      ptrdiff_t delta = target - (p - 1);

+ -    p[-1] = A64I_B | ((uint32_t)(delta) & 0x03ffffffu);

+ +    p[-1] = A64I_B | A64F_S26(delta);

+    }

+  }

+  

+ @@ -1919,7 +1919,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)

+    }

+    /* Patch exit branch. */

+    target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;

+ -  p[-1] = A64I_B | (((target-p)+1)&0x03ffffffu);

+ +  p[-1] = A64I_B | A64F_S26((target-p)+1);

+  }

+  

+  /* Prepare tail of code. */

+ @@ -1982,40 +1982,50 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)

+  {

+    MCode *p = T->mcode;

+    MCode *pe = (MCode *)((char *)p + T->szmcode);

+ -  MCode *cstart = NULL, *cend = p;

+ +  MCode *cstart = NULL;

+    MCode *mcarea = lj_mcode_patch(J, p, 0);

+    MCode *px = exitstub_trace_addr(T, exitno);

+ +  /* Note: this assumes a trace exit is only ever patched once. */

+    for (; p < pe; p++) {

+      /* Look for exitstub branch, replace with branch to target. */

+ +    ptrdiff_t delta = target - p;

+      MCode ins = A64I_LE(*p);

+      if ((ins & 0xff000000u) == 0x54000000u &&

+  	((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) {

+ -      /* Patch bcc exitstub. */

+ -      *p = A64I_LE((ins & 0xff00001fu) | (((target-p)<<5) & 0x00ffffe0u));

+ -      cend = p+1;

+ -      if (!cstart) cstart = p;

+ +      /* Patch bcc, if within range. */

+ +      if (A64F_S_OK(delta, 19)) {

+ +	*p = A64I_LE((ins & 0xff00001fu) | A64F_S19(delta));

+ +	if (!cstart) cstart = p;

+ +      }

+      } else if ((ins & 0xfc000000u) == 0x14000000u &&

+  	       ((ins ^ (px-p)) & 0x03ffffffu) == 0) {

+ -      /* Patch b exitstub. */

+ -      *p = A64I_LE((ins & 0xfc000000u) | ((target-p) & 0x03ffffffu));

+ -      cend = p+1;

+ +      /* Patch b. */

+ +      lua_assert(A64F_S_OK(delta, 26));

+ +      *p = A64I_LE((ins & 0xfc000000u) | A64F_S26(delta));

+        if (!cstart) cstart = p;

+      } else if ((ins & 0x7e000000u) == 0x34000000u &&

+  	       ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) {

+ -      /* Patch cbz/cbnz exitstub. */

+ -      *p = A64I_LE((ins & 0xff00001f) | (((target-p)<<5) & 0x00ffffe0u));

+ -      cend = p+1;

+ -      if (!cstart) cstart = p;

+ +      /* Patch cbz/cbnz, if within range. */

+ +      if (A64F_S_OK(delta, 19)) {

+ +	*p = A64I_LE((ins & 0xff00001fu) | A64F_S19(delta));

+ +	if (!cstart) cstart = p;

+ +      }

+      } else if ((ins & 0x7e000000u) == 0x36000000u &&

+  	       ((ins ^ ((px-p)<<5)) & 0x0007ffe0u) == 0) {

+ -      /* Patch tbz/tbnz exitstub. */

+ -      *p = A64I_LE((ins & 0xfff8001fu) | (((target-p)<<5) & 0x0007ffe0u));

+ -      cend = p+1;

+ -      if (!cstart) cstart = p;

+ +      /* Patch tbz/tbnz, if within range. */

+ +      if (A64F_S_OK(delta, 14)) {

+ +	*p = A64I_LE((ins & 0xfff8001fu) | A64F_S14(delta));

+ +	if (!cstart) cstart = p;

+ +      }

+      }

+    }

+ -  lua_assert(cstart != NULL);

+ -  lj_mcode_sync(cstart, cend);

+ +  {  /* Always patch long-range branch in exit stub itself. */

+ +    ptrdiff_t delta = target - px;

+ +    lua_assert(A64F_S_OK(delta, 26));

+ +    *px = A64I_B | A64F_S26(delta);

+ +    if (!cstart) cstart = px;

+ +  }

+ +  lj_mcode_sync(cstart, px+1);

+    lj_mcode_patch(J, mcarea, 1);

+  }

+  

+ diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h

+ index 6da4c7d..1001b1d 100644

+ --- a/src/lj_emit_arm64.h

+ +++ b/src/lj_emit_arm64.h

+ @@ -241,7 +241,7 @@ static void emit_loadk(ASMState *as, Reg rd, uint64_t u64, int is64)

+  #define mcpofs(as, k) \

+    ((intptr_t)((uintptr_t)(k) - (uintptr_t)(as->mcp - 1)))

+  #define checkmcpofs(as, k) \

+ -  ((((mcpofs(as, k)>>2) + 0x00040000) >> 19) == 0)

+ +  (A64F_S_OK(mcpofs(as, k)>>2, 19))

+  

+  static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);

+  

+ @@ -312,7 +312,7 @@ static void emit_cond_branch(ASMState *as, A64CC cond, MCode *target)

+  {

+    MCode *p = --as->mcp;

+    ptrdiff_t delta = target - p;

+ -  lua_assert(((delta + 0x40000) >> 19) == 0);

+ +  lua_assert(A64F_S_OK(delta, 19));

+    *p = A64I_BCC | A64F_S19(delta) | cond;

+  }

+  

+ @@ -320,24 +320,24 @@ static void emit_branch(ASMState *as, A64Ins ai, MCode *target)

+  {

+    MCode *p = --as->mcp;

+    ptrdiff_t delta = target - p;

+ -  lua_assert(((delta + 0x02000000) >> 26) == 0);

+ -  *p = ai | ((uint32_t)delta & 0x03ffffffu);

+ +  lua_assert(A64F_S_OK(delta, 26));

+ +  *p = ai | A64F_S26(delta);

+  }

+  

+  static void emit_tnb(ASMState *as, A64Ins ai, Reg r, uint32_t bit, MCode *target)

+  {

+    MCode *p = --as->mcp;

+    ptrdiff_t delta = target - p;

+ -  lua_assert(bit < 63 && ((delta + 0x2000) >> 14) == 0);

+ +  lua_assert(bit < 63 && A64F_S_OK(delta, 14));

+    if (bit > 31) ai |= A64I_X;

+ -  *p = ai | A64F_BIT(bit & 31) | A64F_S14((uint32_t)delta & 0x3fffu) | r;

+ +  *p = ai | A64F_BIT(bit & 31) | A64F_S14(delta) | r;

+  }

+  

+  static void emit_cnb(ASMState *as, A64Ins ai, Reg r, MCode *target)

+  {

+    MCode *p = --as->mcp;

+    ptrdiff_t delta = target - p;

+ -  lua_assert(((delta + 0x40000) >> 19) == 0);

+ +  lua_assert(A64F_S_OK(delta, 19));

+    *p = ai | A64F_S19(delta) | r;

+  }

+  

+ @@ -347,8 +347,8 @@ static void emit_call(ASMState *as, void *target)

+  {

+    MCode *p = --as->mcp;

+    ptrdiff_t delta = (char *)target - (char *)p;

+ -  if ((((delta>>2) + 0x02000000) >> 26) == 0) {

+ -    *p = A64I_BL | ((uint32_t)(delta>>2) & 0x03ffffffu);

+ +  if (A64F_S_OK(delta>>2, 26)) {

+ +    *p = A64I_BL | A64F_S26(delta>>2);

+    } else {  /* Target out of range: need indirect call. But don't use R0-R7. */

+      Reg r = ra_allock(as, i64ptr(target),

+  		      RSET_RANGE(RID_X8, RID_MAX_GPR)-RSET_FIXED);

+ diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h

+ index 520023a..a207a2b 100644

+ --- a/src/lj_target_arm64.h

+ +++ b/src/lj_target_arm64.h

+ @@ -132,9 +132,9 @@ static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno)

+  #define A64F_IMMR(x)	((x) << 16)

+  #define A64F_U16(x)	((x) << 5)

+  #define A64F_U12(x)	((x) << 10)

+ -#define A64F_S26(x)	(x)

+ +#define A64F_S26(x)	(((uint32_t)(x) & 0x03ffffffu))

+  #define A64F_S19(x)	(((uint32_t)(x) & 0x7ffffu) << 5)

+ -#define A64F_S14(x)	((x) << 5)

+ +#define A64F_S14(x)	(((uint32_t)(x) & 0x3fffu) << 5)

+  #define A64F_S9(x)	((x) << 12)

+  #define A64F_BIT(x)	((x) << 19)

+  #define A64F_SH(sh, x)	(((sh) << 22) | ((x) << 10))

+ @@ -145,6 +145,9 @@ static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno)

+  #define A64F_LSL16(x)	(((x) / 16) << 21)

+  #define A64F_BSH(sh)	((sh) << 10)

+  

+ +/* Check for valid field range. */

+ +#define A64F_S_OK(x, b)	((((x) + (1 << (b-1))) >> (b)) == 0)

+ +

+  typedef enum A64Ins {

+    A64I_S = 0x20000000,

+    A64I_X = 0x80000000,

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,24 @@ 

+ From 9b41062156779160b88fe5e1eb1ece1ee1fe6a74 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 24 Jun 2018 14:10:21 +0200

+ Subject: [PATCH 48/72] DynASM: Fix warning.

+ 

+ ---

+  dynasm/dasm_arm64.h | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/dynasm/dasm_arm64.h b/dynasm/dasm_arm64.h

+ index 47e1e07..ff21236 100644

+ --- a/dynasm/dasm_arm64.h

+ +++ b/dynasm/dasm_arm64.h

+ @@ -427,6 +427,7 @@ int dasm_encode(Dst_DECL, void *buffer)

+  	  break;

+  	case DASM_REL_LG:

+  	  CK(n >= 0, UNDEF_LG);

+ +	  /* fallthrough */

+  	case DASM_REL_PC:

+  	  CK(n >= 0, UNDEF_PC);

+  	  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) + 4;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,28 @@ 

+ From 26f1023819efb843e10014232cd88bb1d52ea4f5 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Wed, 22 Aug 2018 13:35:41 +0200

+ Subject: [PATCH 49/72] DynASM/x86: Fix vroundps/vroundpd encoding.

+ 

+ Thanks to Alexander Nasonov.

+ ---

+  dynasm/dasm_x86.lua | 4 ++--

+  1 file changed, 2 insertions(+), 2 deletions(-)

+ 

+ diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua

+ index 73502f6..7f536af 100644

+ --- a/dynasm/dasm_x86.lua

+ +++ b/dynasm/dasm_x86.lua

+ @@ -1537,8 +1537,8 @@ local map_op = {

+    vrcpss_3 =	"rrro:F30FV53rM|rrx/ood:",

+    vrsqrtps_2 =	"rmoy:0Fu52rM",

+    vrsqrtss_3 =	"rrro:F30FV52rM|rrx/ood:",

+ -  vroundpd_3 =	"rmioy:660F3AV09rMU",

+ -  vroundps_3 =	"rmioy:660F3AV08rMU",

+ +  vroundpd_3 =	"rmioy:660F3Au09rMU",

+ +  vroundps_3 =	"rmioy:660F3Au08rMU",

+    vroundsd_4 =	"rrrio:660F3AV0BrMU|rrxi/ooq:",

+    vroundss_4 =	"rrrio:660F3AV0ArMU|rrxi/ood:",

+    vshufpd_4 =	"rrmioy:660FVC6rMU",

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,27 @@ 

+ From 646148e747759f0af3b47f9bd287cedd7e174631 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 13 Sep 2018 17:58:50 +0200

+ Subject: [PATCH 50/72] Fix memory probing allocator to check for valid end

+  address, too.

+ 

+ ---

+  src/lj_alloc.c | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_alloc.c b/src/lj_alloc.c

+ index f3b6a54..33a2eb8 100644

+ --- a/src/lj_alloc.c

+ +++ b/src/lj_alloc.c

+ @@ -255,7 +255,8 @@ static void *mmap_probe(size_t size)

+    for (retry = 0; retry < LJ_ALLOC_MMAP_PROBE_MAX; retry++) {

+      void *p = mmap((void *)hint_addr, size, MMAP_PROT, MMAP_FLAGS_PROBE, -1, 0);

+      uintptr_t addr = (uintptr_t)p;

+ -    if ((addr >> LJ_ALLOC_MBITS) == 0 && addr >= LJ_ALLOC_MMAP_PROBE_LOWER) {

+ +    if ((addr >> LJ_ALLOC_MBITS) == 0 && addr >= LJ_ALLOC_MMAP_PROBE_LOWER &&

+ +	((addr + size) >> LJ_ALLOC_MBITS) == 0) {

+        /* We got a suitable address. Bump the hint address. */

+        hint_addr = addr + size;

+        errno = olderr;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,39 @@ 

+ From 9c1b637898f38dd4606da08ba1a82a174c3e64b6 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 14 Oct 2018 15:12:59 +0200

+ Subject: [PATCH 51/72] MIPS/MIPS64: Fix TSETR barrier (again).

+ 

+ ---

+  src/vm_mips.dasc   | 2 +-

+  src/vm_mips64.dasc | 2 +-

+  2 files changed, 2 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc

+ index 1afd611..f324812 100644

+ --- a/src/vm_mips.dasc

+ +++ b/src/vm_mips.dasc

+ @@ -4317,7 +4317,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)

+      |  ins_next2

+      |

+      |7:  // Possible table write barrier for the value. Skip valiswhite check.

+ -    |  barrierback TAB:CARG2, TMP3, TMP0, <2

+ +    |  barrierback TAB:CARG2, TMP3, CRET1, <2

+      break;

+  

+    case BC_TSETM:

+ diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc

+ index 0a3f8e5..1682c81 100644

+ --- a/src/vm_mips64.dasc

+ +++ b/src/vm_mips64.dasc

+ @@ -4263,7 +4263,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)

+      |  ins_next2

+      |

+      |7:  // Possible table write barrier for the value. Skip valiswhite check.

+ -    |  barrierback TAB:CARG2, TMP3, TMP0, <2

+ +    |  barrierback TAB:CARG2, TMP3, CRET1, <2

+      break;

+  

+    case BC_TSETM:

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,29 @@ 

+ From 0a9ff94c4a1fcec2c310dcb092da694f23186e23 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Sun, 14 Oct 2018 15:21:37 +0200

+ Subject: [PATCH 52/72] Actually implement maxirconst trace limit.

+ 

+ Suggested by spacewander.

+ ---

+  src/lj_record.c | 5 +++--

+  1 file changed, 3 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/lj_record.c b/src/lj_record.c

+ index 1a2b1c5..7f37d6c 100644

+ --- a/src/lj_record.c

+ +++ b/src/lj_record.c

+ @@ -2470,8 +2470,9 @@ void lj_record_ins(jit_State *J)

+  #undef rbv

+  #undef rcv

+  

+ -  /* Limit the number of recorded IR instructions. */

+ -  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord])

+ +  /* Limit the number of recorded IR instructions and constants. */

+ +  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||

+ +      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])

+      lj_trace_err(J, LJ_TRERR_TRACEOV);

+  }

+  

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,27 @@ 

+ From 3404183e2387f48e3464bd79116d3e8021ca781e Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:02:15 +0100

+ Subject: [PATCH 53/72] Better detection of MinGW build.

+ 

+ ---

+  src/Makefile | 4 ++++

+  1 file changed, 4 insertions(+)

+ 

+ diff --git a/src/Makefile b/src/Makefile

+ index 24e8c0e..962aa94 100644

+ --- a/src/Makefile

+ +++ b/src/Makefile

+ @@ -165,6 +165,10 @@ else

+      HOST_SYS= Windows

+      HOST_MSYS= mingw

+    endif

+ +  ifneq (,$(findstring MSYS,$(HOST_SYS)))

+ +    HOST_SYS= Windows

+ +    HOST_MSYS= mingw

+ +  endif

+    ifneq (,$(findstring CYGWIN,$(HOST_SYS)))

+      HOST_SYS= Windows

+      HOST_MSYS= cygwin

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,131 @@ 

+ commit 749e99ce2a88bf337bd2f6279940d6761ce5f616

+ Merge: e2cc89b 380e440

+ Author: Mike Pall <mike>

+ Date:   Thu Jan 10 12:24:17 2019 +0100

+ 

+     Merge branch 'master' into v2.1

+ 

+ From 380e4409a70725df85034f02c968b6ebd7a5e513 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:19:30 +0100

+ Subject: [PATCH 54/72] Fix overflow of snapshot map offset.

+ 

+ Thanks to Yichun Zhang.

+ ---

+  src/lj_jit.h      | 10 +++++-----

+  src/lj_opt_loop.c |  8 ++++----

+  src/lj_snap.c     |  6 +++---

+  3 files changed, 12 insertions(+), 12 deletions(-)

+ 

+ diff --git a/src/lj_jit.h b/src/lj_jit.h

+ index 3f38d28..0bc6258 100644

+ --- a/src/lj_jit.h

+ +++ b/src/lj_jit.h

+ @@ -163,7 +163,7 @@ typedef struct MCLink {

+  

+  /* Stack snapshot header. */

+  typedef struct SnapShot {

+ -  uint16_t mapofs;	/* Offset into snapshot map. */

+ +  uint32_t mapofs;	/* Offset into snapshot map. */

+    IRRef1 ref;		/* First IR ref for this snapshot. */

+    uint8_t nslots;	/* Number of valid slots. */

+    uint8_t topslot;	/* Maximum frame extent. */

+ @@ -217,17 +217,15 @@ typedef enum {

+  /* Trace object. */

+  typedef struct GCtrace {

+    GCHeader;

+ -  uint8_t topslot;	/* Top stack slot already checked to be allocated. */

+ -  uint8_t linktype;	/* Type of link. */

+ +  uint16_t nsnap;	/* Number of snapshots. */

+    IRRef nins;		/* Next IR instruction. Biased with REF_BIAS. */

+  #if LJ_GC64

+    uint32_t unused_gc64;

+  #endif

+    GCRef gclist;

+    IRIns *ir;		/* IR instructions/constants. Biased with REF_BIAS. */

+    IRRef nk;		/* Lowest IR constant. Biased with REF_BIAS. */

+ -  uint16_t nsnap;	/* Number of snapshots. */

+ -  uint16_t nsnapmap;	/* Number of snapshot map elements. */

+ +  uint32_t nsnapmap;	/* Number of snapshot map elements. */

+    SnapShot *snap;	/* Snapshot array. */

+    SnapEntry *snapmap;	/* Snapshot map. */

+    GCRef startpt;	/* Starting prototype. */

+ @@ -241,6 +239,8 @@ typedef struct GCtrace {

+    TraceNo1 nextroot;	/* Next root trace for same prototype. */

+    TraceNo1 nextside;	/* Next side trace of same root trace. */

+    uint8_t sinktags;	/* Trace has SINK tags. */

+ +  uint8_t topslot;	/* Top stack slot already checked to be allocated. */

+ +  uint8_t linktype;	/* Type of link. */

+    uint8_t unused1;

+  #ifdef LUAJIT_USE_GDBJIT

+    void *gdbjit_entry;	/* GDB JIT entry. */

+ diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c

+ index 36317b3..cc88111 100644

+ --- a/src/lj_opt_loop.c

+ +++ b/src/lj_opt_loop.c

+ @@ -223,7 +223,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap,

+    }

+    J->guardemit.irt = 0;

+    /* Setup new snapshot. */

+ -  snap->mapofs = (uint16_t)nmapofs;

+ +  snap->mapofs = (uint32_t)nmapofs;

+    snap->ref = (IRRef1)J->cur.nins;

+    snap->nslots = nslots;

+    snap->topslot = osnap->topslot;

+ @@ -251,7 +251,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap,

+    nmap += nn;

+    while (omap < nextmap)  /* Copy PC + frame links. */

+      *nmap++ = *omap++;

+ -  J->cur.nsnapmap = (uint16_t)(nmap - J->cur.snapmap);

+ +  J->cur.nsnapmap = (uint32_t)(nmap - J->cur.snapmap);

+  }

+  

+  typedef struct LoopState {

+ @@ -362,7 +362,7 @@ static void loop_unroll(jit_State *J)

+      }

+    }

+    if (!irt_isguard(J->guardemit))  /* Drop redundant snapshot. */

+ -    J->cur.nsnapmap = (uint16_t)J->cur.snap[--J->cur.nsnap].mapofs;

+ +    J->cur.nsnapmap = (uint32_t)J->cur.snap[--J->cur.nsnap].mapofs;

+    lua_assert(J->cur.nsnapmap <= J->sizesnapmap);

+    *psentinel = J->cur.snapmap[J->cur.snap[0].nent];  /* Restore PC. */

+  

+ @@ -376,7 +376,7 @@ static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap, MSize nsnapmap)

+    SnapShot *snap = &J->cur.snap[nsnap-1];

+    SnapEntry *map = J->cur.snapmap;

+    map[snap->mapofs + snap->nent] = map[J->cur.snap[0].nent];  /* Restore PC. */

+ -  J->cur.nsnapmap = (uint16_t)nsnapmap;

+ +  J->cur.nsnapmap = (uint32_t)nsnapmap;

+    J->cur.nsnap = nsnap;

+    J->guardemit.irt = 0;

+    lj_ir_rollback(J, ins);

+ diff --git a/src/lj_snap.c b/src/lj_snap.c

+ index e891f7a..73f2500 100644

+ --- a/src/lj_snap.c

+ +++ b/src/lj_snap.c

+ @@ -129,11 +129,11 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap)

+    nent = snapshot_slots(J, p, nslots);

+    snap->nent = (uint8_t)nent;

+    nent += snapshot_framelinks(J, p + nent, &snap->topslot);

+ -  snap->mapofs = (uint16_t)nsnapmap;

+ +  snap->mapofs = (uint32_t)nsnapmap;

+    snap->ref = (IRRef1)J->cur.nins;

+    snap->nslots = (uint8_t)nslots;

+    snap->count = 0;

+ -  J->cur.nsnapmap = (uint16_t)(nsnapmap + nent);

+ +  J->cur.nsnapmap = (uint32_t)(nsnapmap + nent);

+  }

+  

+  /* Add or merge a snapshot. */

+ @@ -294,7 +294,7 @@ void lj_snap_shrink(jit_State *J)

+    snap->nent = (uint8_t)m;

+    nlim = J->cur.nsnapmap - snap->mapofs - 1;

+    while (n <= nlim) map[m++] = map[n++];  /* Move PC + frame links down. */

+ -  J->cur.nsnapmap = (uint16_t)(snap->mapofs + m);  /* Free up space in map. */

+ +  J->cur.nsnapmap = (uint32_t)(snap->mapofs + m);  /* Free up space in map. */

+  }

+  

+  /* -- Snapshot access ----------------------------------------------------- */

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,31 @@ 

+ From 20e4c529458fa42ef6651a0042e3955723ee20c2 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:28:24 +0100

+ Subject: [PATCH 55/72] DynASM/PPC: Fix shadowed variable.

+ 

+ Cleanup only, bug cannot trigger.

+ Thanks to Domingo Alvarez Duarte.

+ ---

+  dynasm/dasm_ppc.lua | 6 +++---

+  1 file changed, 3 insertions(+), 3 deletions(-)

+ 

+ diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua

+ index 4e1656e..77031fb 100644

+ --- a/dynasm/dasm_ppc.lua

+ +++ b/dynasm/dasm_ppc.lua

+ @@ -1056,9 +1056,9 @@ map_op[".template__"] = function(params, template, nparams)

+      elseif p == "M" then

+        op = op + parse_shiftmask(params[n], false); n = n + 1

+      elseif p == "J" or p == "K" then

+ -      local mode, n, s = parse_label(params[n], false)

+ -      if p == "K" then n = n + 2048 end

+ -      waction("REL_"..mode, n, s, 1)

+ +      local mode, m, s = parse_label(params[n], false)

+ +      if p == "K" then m = m + 2048 end

+ +      waction("REL_"..mode, m, s, 1)

+        n = n + 1

+      elseif p == "0" then

+        if band(shr(op, rs), 31) == 0 then werror("cannot use r0") end

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,31 @@ 

+ From 5c911998a3c85d024a8006feafc68d0b4c962fd8 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:32:08 +0100

+ Subject: [PATCH 56/72] DynASM/MIPS: Fix shadowed variable.

+ 

+ Cleanup only, bug cannot trigger.

+ Thanks to Domingo Alvarez Duarte.

+ ---

+  dynasm/dasm_mips.lua | 6 +++---

+  1 file changed, 3 insertions(+), 3 deletions(-)

+ 

+ diff --git a/dynasm/dasm_mips.lua b/dynasm/dasm_mips.lua

+ index 8e250ce..af53042 100644

+ --- a/dynasm/dasm_mips.lua

+ +++ b/dynasm/dasm_mips.lua

+ @@ -757,9 +757,9 @@ map_op[".template__"] = function(params, template, nparams)

+      elseif p == "X" then

+        op = op + parse_index(params[n]); n = n + 1

+      elseif p == "B" or p == "J" then

+ -      local mode, n, s = parse_label(params[n], false)

+ -      if p == "B" then n = n + 2048 end

+ -      waction("REL_"..mode, n, s, 1)

+ +      local mode, m, s = parse_label(params[n], false)

+ +      if p == "B" then m = m + 2048 end

+ +      waction("REL_"..mode, m, s, 1)

+        n = n + 1

+      elseif p == "A" then

+        op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,26 @@ 

+ From 61464b0a5b685489bee7b6680c0e9663f2143a84 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:37:09 +0100

+ Subject: [PATCH 57/72] Fix MinGW build.

+ 

+ Thanks to Victor Bombi.

+ ---

+  src/Makefile | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/Makefile b/src/Makefile

+ index 962aa94..2c780de 100644

+ --- a/src/Makefile

+ +++ b/src/Makefile

+ @@ -194,7 +194,7 @@ CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)

+  LDOPTIONS= $(CCDEBUG) $(LDFLAGS)

+  

+  HOST_CC= $(CC)

+ -HOST_RM= rm -f

+ +HOST_RM?= rm -f

+  # If left blank, minilua is built and used. You can supply an installed

+  # copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua

+  HOST_LUA=

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,32 @@ 

+ From fc63c938b522e147ea728b75f385728bf4a8fc35 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 12:47:28 +0100

+ Subject: [PATCH 58/72] Fix os.date() for wider libc strftime() compatibility.

+ 

+ Thanks to Jesper Lundgren.

+ ---

+  src/lib_os.c | 4 ++--

+  1 file changed, 2 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/lib_os.c b/src/lib_os.c

+ index 9e78d49..ffbc3fd 100644

+ --- a/src/lib_os.c

+ +++ b/src/lib_os.c

+ @@ -205,12 +205,12 @@ LJLIB_CF(os_date)

+      setboolfield(L, "isdst", stm->tm_isdst);

+    } else if (*s) {

+      SBuf *sb = &G(L)->tmpbuf;

+ -    MSize sz = 0;

+ +    MSize sz = 0, retry = 4;

+      const char *q;

+      for (q = s; *q; q++)

+        sz += (*q == '%') ? 30 : 1;  /* Overflow doesn't matter. */

+      setsbufL(sb, L);

+ -    for (;;) {

+ +    while (retry--) {  /* Limit growth for invalid format or empty result. */

+        char *buf = lj_buf_need(sb, sz);

+        size_t len = strftime(buf, sbufsz(sb), s, stm);

+        if (len) {

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,35 @@ 

+ From f0e865dd4861520258299d0f2a56491bd9d602e1 Mon Sep 17 00:00:00 2001

+ From: Mike Pall <mike>

+ Date: Thu, 10 Jan 2019 13:09:17 +0100

+ Subject: [PATCH 59/72] Improve luaL_addlstring().

+ 

+ Thanks to Domingo Alvarez Duarte.

+ ---

+  src/lib_aux.c | 11 +++++++++--

+  1 file changed, 9 insertions(+), 2 deletions(-)

+ 

+ diff --git a/src/lib_aux.c b/src/lib_aux.c

+ index c40565c..2682a38 100644

+ --- a/src/lib_aux.c

+ +++ b/src/lib_aux.c

+ @@ -218,8 +218,15 @@ LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B)

+  

+  LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)

+  {

+ -  while (l--)

+ -    luaL_addchar(B, *s++);

+ +  if (l <= bufffree(B)) {

+ +    memcpy(B->p, s, l);

+ +    B->p += l;

+ +  } else {

+ +    emptybuffer(B);

+ +    lua_pushlstring(B->L, s, l);

+ +    B->lvl++;

+ +    adjuststack(B);

+ +  }

+  }

+  

+  LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,34 @@ 

+ From 43a3893b0d7d82bfbfd13bf458a5906f755989c9 Mon Sep 17 00:00:00 2001

+ From: Patrick Galizia <pgalizia.qdt@qualcommdatacenter.com>

+ Date: Fri, 24 Aug 2018 11:02:15 -0400

+ Subject: [PATCH 60/72] Fix arm64 register allocation issue for XLOAD.

+ 

+ For the arm64 implementation of asm_xload(), it is possible for

+ the dest register selected to be the same as one of the source

+ registers generated in the asm_fusexref() call.  To prevent this,

+ exclude the dest register from the list of allowed registers for

+ that call.

+ 

+ Thanks to Javier for guidance as well as his script to replicate

+ the issue.

+ ---

+  src/lj_asm_arm64.h | 3 ++-

+  1 file changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index baafa21..045f260 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -1008,7 +1008,8 @@ static void asm_xload(ASMState *as, IRIns *ir)

+  {

+    Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+    lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));

+ -  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);

+ +  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1,

+ +               rset_exclude(RSET_GPR, dest));

+  }

+  

+  static void asm_xstore(ASMState *as, IRIns *ir)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,59 @@ 

+ From ec0d8427ade9346d356623072fcb91c2d11e3bda Mon Sep 17 00:00:00 2001

+ From: Patrick Galizia <pgalizia.qdt@qualcommdatacenter.com>

+ Date: Wed, 28 Nov 2018 14:14:35 -0500

+ Subject: [PATCH 61/72] Fix arm64 register allocation issue for XLOAD.

+ 

+ For arm64, it's possible for both IRRefs to fail asm_isk32(), but

+ one of them pass irref_isk().  Add a secondary check for the latter

+ call if both asm_isk32() calls fail.

+ ---

+  src/lj_asm_arm64.h | 18 +++++++++++++-----

+  1 file changed, 13 insertions(+), 5 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index 045f260..ce49cde 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -295,9 +295,18 @@ static void asm_fusexref(ASMState *as, A64Ins ai, Reg rd, IRRef ref,

+        } else if (asm_isk32(as, ir->op1, &ofs)) {

+  	ref = ir->op2;

+        } else {

+ -	Reg rn = ra_alloc1(as, ir->op1, allow);

+ -	IRIns *irr = IR(ir->op2);

+ +	IRRef ref1 = ir->op1;

+ +	IRRef ref2 = ir->op2;

+ +	Reg rn;

+ +	IRIns *irr;

+  	uint32_t m;

+ +

+ +	if (irref_isk(ir->op1)) {

+ +	  ref1 = ir->op2;

+ +	  ref2 = ir->op1;

+ +	}

+ +	rn = ra_alloc1(as, ref1, allow);

+ +	irr = IR(ref2);

+  	if (irr+1 == ir && !ra_used(irr) &&

+  	    irr->o == IR_ADD && irref_isk(irr->op2)) {

+  	  ofs = sizeof(GCstr) + IR(irr->op2)->i;

+ @@ -307,7 +316,7 @@ static void asm_fusexref(ASMState *as, A64Ins ai, Reg rd, IRRef ref,

+  	    goto skipopm;

+  	  }

+  	}

+ -	m = asm_fuseopm(as, 0, ir->op2, rset_exclude(allow, rn));

+ +	m = asm_fuseopm(as, 0, ref2, rset_exclude(allow, rn));

+  	ofs = sizeof(GCstr);

+        skipopm:

+  	emit_lso(as, ai, rd, rd, ofs);

+ @@ -1008,8 +1017,7 @@ static void asm_xload(ASMState *as, IRIns *ir)

+  {

+    Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+    lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));

+ -  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1,

+ -               rset_exclude(RSET_GPR, dest));

+ +  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);

+  }

+  

+  static void asm_xstore(ASMState *as, IRIns *ir)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,50 @@ 

+ From 1fae7b08e319ba4028d303b09de72b026109a269 Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@gotplt.org>

+ Date: Fri, 22 Feb 2019 19:05:38 +0000

+ Subject: [PATCH 62/72] Remove redundant emit_check_ofs

+ 

+ Even if the offset is a constant, it is not 32-bit since it failed

+ that check earlier before it came here.  The code is thus useless and

+ hence removed.  This also fixes inconsistencies with op1/op2 renaming

+ that were introduced in PR #438.  They were never triggered because

+ the code path is effectively dead for arm64.

+ ---

+  src/lj_asm_arm64.h | 15 +--------------

+  1 file changed, 1 insertion(+), 14 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index ce49cde..c214e10 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -298,27 +298,14 @@ static void asm_fusexref(ASMState *as, A64Ins ai, Reg rd, IRRef ref,

+  	IRRef ref1 = ir->op1;

+  	IRRef ref2 = ir->op2;

+  	Reg rn;

+ -	IRIns *irr;

+ -	uint32_t m;

+  

+  	if (irref_isk(ir->op1)) {

+  	  ref1 = ir->op2;

+  	  ref2 = ir->op1;

+  	}

+  	rn = ra_alloc1(as, ref1, allow);

+ -	irr = IR(ref2);

+ -	if (irr+1 == ir && !ra_used(irr) &&

+ -	    irr->o == IR_ADD && irref_isk(irr->op2)) {

+ -	  ofs = sizeof(GCstr) + IR(irr->op2)->i;

+ -	  if (emit_checkofs(ai, ofs)) {

+ -	    Reg rm = ra_alloc1(as, irr->op1, rset_exclude(allow, rn));

+ -	    m = A64F_M(rm) | A64F_EX(A64EX_SXTW);

+ -	    goto skipopm;

+ -	  }

+ -	}

+ -	m = asm_fuseopm(as, 0, ref2, rset_exclude(allow, rn));

+ +	uint32_t m = asm_fuseopm(as, 0, ref2, rset_exclude(allow, rn));

+  	ofs = sizeof(GCstr);

+ -      skipopm:

+  	emit_lso(as, ai, rd, rd, ofs);

+  	emit_dn(as, A64I_ADDx^m, rd, rn);

+  	return;

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,73 @@ 

+ From 8fc4ce1c981967fccd5366ace6add6d14cfcde89 Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@gotplt.org>

+ Date: Mon, 25 Feb 2019 14:40:39 +0000

+ Subject: [PATCH 63/72] aarch64: Use the xzr register whenever possible

+ 

+ Using the xzr register for store inputs and the second operand of

+ arithmetic operations frees up a register for use elsewhere.

+ ---

+  src/lj_asm_arm64.h | 31 ++++++++++++++++++++++++++++---

+  1 file changed, 28 insertions(+), 3 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index c214e10..a826687 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -1007,10 +1007,30 @@ static void asm_xload(ASMState *as, IRIns *ir)

+    asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);

+  }

+  

+ +static int maybe_zero_val(ASMState *as, IRRef ref)

+ +{

+ +  IRIns *ir = IR(ref);

+ +

+ +  switch(ir->o) {

+ +  case IR_KNULL:

+ +    return 1;

+ +  case IR_KINT:

+ +    return 0 == ir->i;

+ +  case IR_KINT64:

+ +    return 0 == ir_kint64(ir)->u64;

+ +  }

+ +

+ +  return 0;

+ +}

+ +

+  static void asm_xstore(ASMState *as, IRIns *ir)

+  {

+    if (ir->r != RID_SINK) {

+ -    Reg src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+ +    Reg src;

+ +    if (irref_isk(ir->op2) && maybe_zero_val(as, ir->op2))

+ +      src = RID_ZERO;

+ +    else

+ +      src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);

+      asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,

+  		 rset_exclude(RSET_GPR, src));

+    }

+ @@ -1198,7 +1218,12 @@ static void asm_cnew(ASMState *as, IRIns *ir)

+    /* Initialize immutable cdata object. */

+    if (ir->o == IR_CNEWI) {

+      int32_t ofs = sizeof(GCcdata);

+ -    Reg r = ra_alloc1(as, ir->op2, allow);

+ +    Reg r;

+ +    if (irref_isk(ir->op2) && maybe_zero_val(as, ir->op2))

+ +      r = RID_ZERO;

+ +    else

+ +      r = ra_alloc1(as, ir->op2, allow);

+ +

+      lua_assert(sz == 4 || sz == 8);

+      emit_lso(as, sz == 8 ? A64I_STRx : A64I_STRw, r, RID_RET, ofs);

+    } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */

+ @@ -1214,7 +1239,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)

+  

+    /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */

+    {

+ -    Reg r = (id < 65536) ? RID_X1 : ra_allock(as, id, allow);

+ +    Reg r = id == 0 ? RID_ZERO : (id < 65536) ? RID_X1 : ra_allock(as, id, allow);

+      emit_lso(as, A64I_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct));

+      emit_lso(as, A64I_STRH, r, RID_RET, offsetof(GCcdata, ctypeid));

+      emit_d(as, A64I_MOVZw | A64F_U16(~LJ_TCDATA), RID_TMP);

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,62 @@ 

+ From e99ac1bc2df5c1d138bbc98d35d1a1892144cf2b Mon Sep 17 00:00:00 2001

+ From: Sameera Deshpande <sameera.deshpande@linaro.org>

+ Date: Fri, 15 Feb 2019 07:46:16 +0530

+ Subject: [PATCH 65/72] Add support for FNMADD and FNMSUB.

+ 

+ ---

+  src/lj_asm_arm64.h | 32 +++++++++++++++++++++++++++++++-

+  1 file changed, 31 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index a826687..470e65d 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -344,6 +344,35 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air)

+    return 0;

+  }

+  

+ +/* Fuse FP neg-multiply-add/sub. */

+ +static int asm_fusenmadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air)

+ +{

+ +  IRRef ref = ir->op1;

+ +  IRIns *irn = IR(ref);

+ +  if (irn->o != IR_ADD && irn->o != IR_SUB)

+ +    return 0;

+ +

+ +  if (!mayfuse(as, ref))

+ +    return 0;

+ +

+ +  IRRef lref = irn->op1, rref = irn->op2;

+ +  IRIns *irm;

+ +  if (lref != rref &&

+ +      ((mayfuse(as, lref) && (irm = IR(lref), irm->o == IR_MUL) &&

+ +       ra_noreg(irm->r)) ||

+ +       (mayfuse(as, rref) && (irm = IR(rref), irm->o == IR_MUL) &&

+ +       (rref = lref, ra_noreg(irm->r))))) {

+ +    Reg dest = ra_dest(as, ir, RSET_FPR);

+ +    Reg add = ra_hintalloc(as, rref, dest, RSET_FPR);

+ +    Reg left = ra_alloc2(as, irm,

+ +			 rset_exclude(rset_exclude(RSET_FPR, dest), add));

+ +    Reg right = (left >> 8); left &= 255;

+ +    emit_dnma(as, (irn->o == IR_ADD ? ai : air), (dest & 31), (left & 31), (right & 31), (add & 31));

+ +    return 1;

+ +  }

+ +  return 0;

+ +}

+ +

+  /* Fuse BAND + BSHL/BSHR into UBFM. */

+  static int asm_fuseandshift(ASMState *as, IRIns *ir)

+  {

+ @@ -1481,7 +1510,8 @@ static void asm_mod(ASMState *as, IRIns *ir)

+  static void asm_neg(ASMState *as, IRIns *ir)

+  {

+    if (irt_isnum(ir->t)) {

+ -    asm_fpunary(as, ir, A64I_FNEGd);

+ +    if (!asm_fusenmadd(as, ir, A64I_FNMADDd))

+ +      asm_fpunary(as, ir, A64I_FNEGd);

+      return;

+    }

+    asm_intneg(as, ir);

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,36 @@ 

+ From 372bb8b22546663ba57e69fad75c97cfd004ac63 Mon Sep 17 00:00:00 2001

+ From: Vivien HENRIET <bubuabu@bubuabu.org>

+ Date: Wed, 30 Jan 2019 23:44:51 +0100

+ Subject: [PATCH 66/72] Fix os.date() for timezone change awareness

+ 

+ On POSIX target, system timezone change are not taken into account.

+ To reproduce,

+ 1. call os.date()

+ 2. change your timezone

+ 3. call os.date() within the same luajit instance

+ 

+ On POSIX target, os.date use localtime_r to retrieve time.

+ On other target, the function localtime is used. But there is a behaviour

+ diference between these two function. localtime acts as if it called tzset

+ which localtime_r don't.

+ 

+ To fix the issue tzset is called before localtime_r.

+ ---

+  src/lib_os.c | 1 +

+  1 file changed, 1 insertion(+)

+ 

+ diff --git a/src/lib_os.c b/src/lib_os.c

+ index ffbc3fd..09dc737 100644

+ --- a/src/lib_os.c

+ +++ b/src/lib_os.c

+ @@ -185,6 +185,7 @@ LJLIB_CF(os_date)

+  #endif

+    } else {

+  #if LJ_TARGET_POSIX

+ +    tzset();

+      stm = localtime_r(&t, &rtm);

+  #else

+      stm = localtime(&t);

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,56 @@ 

+ From 49f19e7b31fc033ac1e9208580b5be31e2b66b19 Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Thu, 14 Mar 2019 23:08:24 +0530

+ Subject: [PATCH 67/72] Revert "FFI: Make FP to U64 conversions match JIT

+  backend behavior."

+ 

+ This reverts commit f5d424afe8b9395f0df05aba905e0e1f6a2262b8.

+ 

+ The patch breaks test 279, i.e.

+ 

+   assert(tostring(bit.band(1ll, 1, 1ull, -1)) == "1ULL")

+ 

+ The patch was put in to make the JIT and interpreter behaviour

+ consistent[1] for float to unsigned int conversions but it ended up

+ making things worse.  There needs to be a better fix for this.

+ 

+ [1] https://github.com/LuaJIT/LuaJIT/pull/415

+ ---

+  src/lj_obj.h | 18 +++++-------------

+  1 file changed, 5 insertions(+), 13 deletions(-)

+ 

+ diff --git a/src/lj_obj.h b/src/lj_obj.h

+ index 72b7ace..c7e4742 100644

+ --- a/src/lj_obj.h

+ +++ b/src/lj_obj.h

+ @@ -942,22 +942,14 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)

+  

+  #define lj_num2int(n)   ((int32_t)(n))

+  

+ -/*

+ -** This must match the JIT backend behavior. In particular for archs

+ -** that don't have a common hardware instruction for this conversion.

+ -** Note that signed FP to unsigned int conversions have an undefined

+ -** result and should never be relied upon in portable FFI code.

+ -** See also: C99 or C11 standard, 6.3.1.4, footnote of (1).

+ -*/

+  static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)

+  {

+ -#if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS

+ -  int64_t i = (int64_t)n;

+ -  if (i < 0) i = (int64_t)(n - 18446744073709551616.0);

+ -  return (uint64_t)i;

+ -#else

+ -  return (uint64_t)n;

+ +#ifdef _MSC_VER

+ +  if (n >= 9223372036854775808.0)  /* They think it's a feature. */

+ +    return (uint64_t)(int64_t)(n - 18446744073709551616.0);

+ +  else

+  #endif

+ +    return (uint64_t)n;

+  }

+  

+  static LJ_AINLINE int32_t numberVint(cTValue *o)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,47 @@ 

+ commit 0513e634f0013083d29af9f5762b225297d3ad6c (HEAD -> v2.1, origin/v2.1)

+ Author: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date:   Fri Apr 12 20:42:55 2019 +0530

+ 

+     Remove built binary from git

+     

+     Oops.

+ 

+ From 9b4f498707569f3ecf81a0561a0d3d91570cec3d Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Fri, 15 Mar 2019 15:51:02 +0530

+ Subject: [PATCH 68/72] bench: Fix build warnings

+ 

+ ---

+  bench/Makefile       |   2 +-

+  bench/luajit-bench   | Bin 571144 -> 571224 bytes

+  bench/luajit-bench.c |   1 +

+  3 files changed, 2 insertions(+), 1 deletion(-)

+ 

+ diff --git a/bench/Makefile b/bench/Makefile

+ index d0c1e8d..87d213a 100644

+ --- a/bench/Makefile

+ +++ b/bench/Makefile

+ @@ -44,7 +44,7 @@ endif

+  LUAJIT_A = ../src/$(FILE_A)

+  

+  $(BENCH_BIN): $(LUAJIT_A) $(BENCH_BIN).c Makefile

+ -	$(CC) $@.c $(DURATION) -g -O3 -c -o $@.o -I ../src

+ +	$(CC) $@.c -std=gnu11 $(DURATION) -g -O3 -c -o $@.o -I ../src

+  	$(CC) $@.o -lpthread $< -lm -ldl -o $@

+  

+  # Build the luajit static library if it doesn't exist.

+ diff --git a/bench/luajit-bench.c b/bench/luajit-bench.c

+ index e7b068d..6603132 100644

+ --- a/bench/luajit-bench.c

+ +++ b/bench/luajit-bench.c

+ @@ -39,6 +39,7 @@

+  #include <argp.h>

+  #include <sys/param.h>

+  #include <string.h>

+ +#include <time.h>

+  

+  #include "lua.h"

+  #include "lualib.h"

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,42 @@ 

+ From 454bea87cff4ff3cd2fd9ae34a3718dd200ce0fb Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Sun, 17 Mar 2019 11:34:04 +0530

+ Subject: [PATCH 69/72] Guard against undefined behaviour when casting from

+  float to unsigned

+ 

+ Only range (-1.0, UINT64_MAX) can be safely converted to unsigned

+ directly, and (-INT64_MAX,INT_64_MAX) through a cast to int64_t first.

+ The remaining range is undefined.

+ 

+ TODO: Do the same for JIT as well as for float to other ranges.

+ ---

+  src/lj_obj.h | 8 +++++++-

+  1 file changed, 7 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_obj.h b/src/lj_obj.h

+ index c7e4742..4ff5944 100644

+ --- a/src/lj_obj.h

+ +++ b/src/lj_obj.h

+ @@ -944,12 +944,18 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)

+  

+  static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)

+  {

+ +  /* Undefined behaviour. This is deliberately not a full check because we

+ +     don't want to slow down compliant code. */

+ +  lua_assert(n >= -9223372036854775809.0);

+  #ifdef _MSC_VER

+    if (n >= 9223372036854775808.0)  /* They think it's a feature. */

+      return (uint64_t)(int64_t)(n - 18446744073709551616.0);

+    else

+  #endif

+ -    return (uint64_t)n;

+ +    if (n > -1.0)

+ +      return (uint64_t)n;

+ +    else

+ +      return (uint64_t)(int64_t)n;

+  }

+  

+  static LJ_AINLINE int32_t numberVint(cTValue *o)

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,25 @@ 

+ From ddca2290b8fa73fc32e88f83105219a1f2be75ff Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Mon, 25 Mar 2019 17:56:53 +0530

+ Subject: [PATCH 70/72] Fix build erro with fnmsub fusing

+ 

+ ---

+  src/lj_asm_arm64.h | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index 470e65d..42a4fae 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -1510,7 +1510,7 @@ static void asm_mod(ASMState *as, IRIns *ir)

+  static void asm_neg(ASMState *as, IRIns *ir)

+  {

+    if (irt_isnum(ir->t)) {

+ -    if (!asm_fusenmadd(as, ir, A64I_FNMADDd))

+ +    if (!asm_fusenmadd(as, ir, A64I_FNMADDd, A64I_FNMSUBd))

+        asm_fpunary(as, ir, A64I_FNEGd);

+      return;

+    }

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,77 @@ 

+ From 70e65633d892765bcbaad3493e5b690abd5402f2 Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Thu, 28 Mar 2019 09:19:34 +0530

+ Subject: [PATCH 71/72] aarch64: better float to unsigned int conversion

+ 

+ A straight float to unsigned conversion has a limited range of (-1.0,

+ UTYPE_MAX) which should be fine in general but for the sake of

+ consistency across the interpreter and the JIT compiler, it is

+ necessary to work a wee bit harder to expand this range to (TYPE_MIN,

+ UTYPE_MAX), which can be done with a simple range check.  This adds a

+ couple of branches but only one of the branches should have a

+ noticeable performance impact on most processors with branch

+ predictors, and that too only if the input number varies wildly in

+ range.

+ 

+ This currently works only for 64-bit conversions, 32-bit is still WIP.

+ ---

+  src/lj_asm_arm64.h    | 30 ++++++++++++++++++++++--------

+  src/lj_target_arm64.h |  1 +

+  2 files changed, 23 insertions(+), 8 deletions(-)

+ 

+ diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h

+ index 42a4fae..c72144a 100644

+ --- a/src/lj_asm_arm64.h

+ +++ b/src/lj_asm_arm64.h

+ @@ -594,14 +594,28 @@ static void asm_conv(ASMState *as, IRIns *ir)

+      } else {

+        Reg left = ra_alloc1(as, lref, RSET_FPR);

+        Reg dest = ra_dest(as, ir, RSET_GPR);

+ -      A64Ins ai = irt_is64(ir->t) ?

+ -	(st == IRT_NUM ?

+ -	 (irt_isi64(ir->t) ? A64I_FCVT_S64_F64 : A64I_FCVT_U64_F64) :

+ -	 (irt_isi64(ir->t) ? A64I_FCVT_S64_F32 : A64I_FCVT_U64_F32)) :

+ -	(st == IRT_NUM ?

+ -	 (irt_isint(ir->t) ? A64I_FCVT_S32_F64 : A64I_FCVT_U32_F64) :

+ -	 (irt_isint(ir->t) ? A64I_FCVT_S32_F32 : A64I_FCVT_U32_F32));

+ -      emit_dn(as, ai, dest, (left & 31));

+ +

+ +      A64Ins ai_signed = st == IRT_NUM ?

+ +        (irt_is64(ir->t) ? A64I_FCVT_S64_F64 : A64I_FCVT_S32_F64) :

+ +        (irt_is64(ir->t) ? A64I_FCVT_S64_F32 : A64I_FCVT_S32_F32);

+ +

+ +      if (irt_isi64(ir->t) || irt_isint(ir->t))

+ +        emit_dn(as, ai_signed, dest, (left & 31));

+ +      else {

+ +        A64Ins ai_unsigned = st == IRT_NUM ?

+ +          (irt_is64(ir->t) ? A64I_FCVT_U64_F64 : A64I_FCVT_U32_F64) :

+ +          (irt_is64(ir->t) ? A64I_FCVT_U64_F32 : A64I_FCVT_U32_F32);

+ +

+ +        MCLabel l_done = emit_label(as);

+ +        emit_dn(as, ai_unsigned, dest, (left & 31));

+ +        MCLabel l_signed = emit_label(as);

+ +	emit_jmp(as, l_done);

+ +        emit_dn(as, ai_signed, dest, (left & 31));

+ +        /* The valid range for float to unsigned int conversion is (-1.0,

+ +           UINT{,64}_MAX-1), but we just compare with 0 to save a load. */

+ +        emit_cond_branch(as, CC_PL, l_signed);

+ +        emit_nm(as, st == IRT_NUM ? A64I_FCMPZd : A64I_FCMPZs, left & 31, 0);

+ +      }

+      }

+    } else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */

+      Reg dest = ra_dest(as, ir, RSET_GPR);

+ diff --git a/src/lj_target_arm64.h b/src/lj_target_arm64.h

+ index a207a2b..2f8357f 100644

+ --- a/src/lj_target_arm64.h

+ +++ b/src/lj_target_arm64.h

+ @@ -279,6 +279,7 @@ typedef enum A64Ins {

+    A64I_STPs = 0x2d000000,

+    A64I_STPd = 0x6d000000,

+    A64I_FCMPd = 0x1e602000,

+ +  A64I_FCMPZs = 0x1e202008,

+    A64I_FCMPZd = 0x1e602008,

+    A64I_FCSELd = 0x1e600c00,

+    A64I_FRINTMd = 0x1e654000,

+ -- 

+ 2.20.1

+ 

@@ -0,0 +1,39 @@ 

+ From f2779155495aee6583abaff4700a7acda80864ef Mon Sep 17 00:00:00 2001

+ From: Siddhesh Poyarekar <siddhesh@sourceware.org>

+ Date: Thu, 28 Mar 2019 10:50:23 +0530

+ Subject: [PATCH 72/72] Better behaviour for float to uint32_t conversions

+ 

+ This is the uint32_t part of the float to unsigned int conversions for

+ the interpreter.  The cast ends up working correctly for x86 but not

+ for aarch64 since fcvtzu sets the result to zero on negative inputs.

+ Work slightly harder to make sure that negative number inputs behave

+ like x86.

+ 

+ This fixes the interpreter but not the JIT compiler, which errors out

+ during the narrowing pass.

+ ---

+  src/lj_cconv.c | 8 +++++++-

+  1 file changed, 7 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/lj_cconv.c b/src/lj_cconv.c

+ index 13b8230..bf8f8e8 100644

+ --- a/src/lj_cconv.c

+ +++ b/src/lj_cconv.c

+ @@ -196,7 +196,13 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,

+        else if (dsize == 2) *(int16_t *)dp = (int16_t)i;

+        else *(int8_t *)dp = (int8_t)i;

+      } else if (dsize == 4) {

+ -      *(uint32_t *)dp = (uint32_t)n;

+ +      /* Undefined behaviour. This is deliberately not a full check because we

+ +       * don't want to slow down compliant code. */

+ +      lua_assert(n >= -2147483649.0);

+ +      if (n > -1.0)

+ +        *(uint32_t *)dp = (uint32_t)n;

+ +      else

+ +        *(uint32_t *)dp = (uint32_t)(int32_t)n;

+      } else if (dsize == 8) {

+        if (!(dinfo & CTF_UNSIGNED))

+  	*(int64_t *)dp = (int64_t)n;

+ -- 

+ 2.20.1

+ 

file modified
+101 -2
@@ -4,12 +4,101 @@ 

  Version:        2.1.0

  %global apiver %(v=%{version}; echo ${v%.${v#[0-9].[0-9].}})

  %global srcver %{version}%{?rctag:-%{rctag}}

- Release:        0.9%{?rctag:%{rctag}}%{?dist}

+ Release:        0.10%{?rctag:%{rctag}}%{?dist}

  Summary:        Just-In-Time Compiler for Lua

  License:        MIT

  URL:            http://luajit.org/

  Source0:        http://luajit.org/download/LuaJIT-%{srcver}.tar.gz

  

+ # Patches from https://github.com/siddhesh/LuaJIT.git

+ # Generated from v2.1 branch against the 2.1.0-beta3 tag.

+ # Some patches, as indicated below, have been modified to account for merge

+ # commits, so care needs to be taken when auto-generating patches so that

+ # existing patches are not replaced.

+ 

+ # Merge commit

+ Patch1: 0001-Fix-LJ_MAX_JSLOTS-assertion-in-rec_check_slots.patch

+ # Merge commit

+ Patch2: 0002-Add-missing-LJ_MAX_JSLOTS-check.patch

+ Patch3: 0003-MIPS-Use-precise-search-for-exit-jump-patching.patch

+ Patch4: 0004-MIPS-Fix-handling-of-spare-long-range-jump-slots.patch

+ Patch5: 0005-MIPS64-Add-soft-float-support-to-JIT-compiler-backen.patch

+ Patch6: 0006-FreeBSD-x64-Avoid-changing-resource-limits-if-not-ne.patch

+ Patch7: 0007-Remove-unused-define.patch

+ Patch8: 0008-Modify-fix-for-warning-from-ar.patch

+ Patch9: 0009-x64-LJ_GC64-Fix-emit_rma.patch

+ Patch10: 0010-PPC-Add-soft-float-support-to-interpreter.patch

+ Patch11: 0011-Use-https-for-freelists.org-links.patch

+ Patch12: 0012-x64-LJ_GC64-Fix-fallback-case-of-asm_fuseloadk64.patch

+ Patch13: 0013-PPC-Add-soft-float-support-to-JIT-compiler-backend.patch

+ Patch14: 0014-x64-LJ_GC64-Fix-type-check-only-variant-of-SLOAD.patch

+ Patch15: 0015-MIPS64-Hide-internal-function.patch

+ # Merge commit

+ Patch16: 0016-DynASM-x86-Fix-potential-REL_A-overflow.patch

+ Patch17: 0017-LJ_GC64-Fix-ir_khash-for-non-string-GCobj.patch

+ Patch18: 0018-LJ_GC64-Make-ASMREF_L-references-64-bit.patch

+ Patch19: 0019-Fix-FOLD-rule-for-strength-reduction-of-widening.patch

+ Patch20: 0020-ARM64-Fix-assembly-of-HREFK.patch

+ Patch21: 0021-MIPS64-Fix-register-allocation-in-assembly-of-HREF.patch

+ Patch22: 0022-ARM64-Fix-xpcall-error-case.patch

+ Patch23: 0023-Fix-saved-bytecode-encapsulated-in-ELF-objects.patch

+ Patch24: 0024-ARM64-Fix-xpcall-error-case-really.patch

+ Patch25: 0025-MIPS64-Fix-xpcall-error-case.patch

+ Patch26: 0026-Fix-IR_BUFPUT-assembly.patch

+ # This patch gets dropped when merged from master to v2.1.

+ # Patch27: 0027-Fix-string.format-c-0.patch

+ Patch28: 0028-Fix-ARMv8-32-bit-subset-detection.patch

+ Patch29: 0029-Fix-LuaJIT-API-docs-for-LUAJIT_MODE_.patch

+ Patch30: 0030-MIPS64-Fix-soft-float-0.0-vs.-0.0-comparison.patch

+ # Merge commit

+ Patch31: 0031-FFI-Don-t-assert-on-1LL-5.2-compatibility-mode-only.patch

+ # Merge commit

+ Patch32: 0032-Fix-GCC-7-Wimplicit-fallthrough-warnings.patch

+ # Merge commit

+ Patch33: 0033-Clear-stack-after-print_jit_status-in-CLI.patch

+ Patch34: 0034-Fix-rechaining-of-pseudo-resurrected-string-keys.patch

+ Patch35: 0035-DynASM-x86-Add-BMI1-and-BMI2-instructions.patch

+ Patch36: 0036-Give-expected-results-for-negative-non-base-10-numbe.patch

+ Patch37: 0037-FFI-Add-tonumber-specialization-for-failed-conversio.patch

+ Patch38: 0038-Bump-copyright-date-to-2018.patch

+ # Merge commit

+ Patch39: 0039-FFI-Make-FP-to-U64-conversions-match-JIT-backend-beh.patch

+ Patch40: 0040-x86-x64-Check-for-jcc-when-using-xor-r-r-in-emit_loa.patch

+ # Merge commit

+ Patch41: 0041-PPC-NetBSD-Fix-endianess-check.patch

+ Patch42: 0042-DynASM-x86-Add-FMA3-instructions.patch

+ Patch43: 0043-x86-Disassemble-FMA3-instructions.patch

+ Patch44: 0044-From-Lua-5.3-assert-accepts-any-type-of-error-object.patch

+ Patch45: 0045-Windows-Add-UWP-support-part-1.patch

+ Patch46: 0046-ARM64-Fix-write-barrier-in-BC_USETS.patch

+ Patch47: 0047-ARM64-Fix-exit-stub-patching.patch

+ Patch48: 0048-DynASM-Fix-warning.patch

+ Patch49: 0049-DynASM-x86-Fix-vroundps-vroundpd-encoding.patch

+ Patch50: 0050-Fix-memory-probing-allocator-to-check-for-valid-end-.patch

+ Patch51: 0051-MIPS-MIPS64-Fix-TSETR-barrier-again.patch

+ Patch52: 0052-Actually-implement-maxirconst-trace-limit.patch

+ Patch53: 0053-Better-detection-of-MinGW-build.patch

+ # Merge commit

+ Patch54: 0054-Fix-overflow-of-snapshot-map-offset.patch

+ Patch55: 0055-DynASM-PPC-Fix-shadowed-variable.patch

+ Patch56: 0056-DynASM-MIPS-Fix-shadowed-variable.patch

+ Patch57: 0057-Fix-MinGW-build.patch

+ Patch58: 0058-Fix-os.date-for-wider-libc-strftime-compatibility.patch

+ Patch59: 0059-Improve-luaL_addlstring.patch

+ Patch60: 0060-Fix-arm64-register-allocation-issue-for-XLOAD.patch

+ Patch61: 0061-Fix-arm64-register-allocation-issue-for-XLOAD.patch

+ Patch62: 0062-Remove-redundant-emit_check_ofs.patch

+ Patch63: 0063-aarch64-Use-the-xzr-register-whenever-possible.patch

+ Patch64: 0064-Merge-in-LuaJIT-test-cleanup-into-the-main-repo.patch

+ Patch65: 0065-Add-support-for-FNMADD-and-FNMSUB.patch

+ Patch66: 0066-Fix-os.date-for-timezone-change-awareness.patch

+ Patch67: 0067-Revert-FFI-Make-FP-to-U64-conversions-match-JIT-back.patch

+ Patch68: 0068-bench-Fix-build-warnings.patch

+ Patch69: 0069-Guard-against-undefined-behaviour-when-casting-from-.patch

+ Patch70: 0070-Fix-build-erro-with-fnmsub-fusing.patch

+ Patch71: 0071-aarch64-better-float-to-unsigned-int-conversion.patch

+ Patch72: 0072-Better-behaviour-for-float-to-uint32_t-conversions.patch

+ 

  ExclusiveArch:  %{arm} %{ix86} x86_64 %{mips} aarch64

  

  BuildRequires:  gcc
@@ -28,7 +117,7 @@ 

  This package contains development files for %{name}.

  

  %prep

- %autosetup -n LuaJIT-%{srcver}

+ %autosetup -n LuaJIT-%{srcver} -p1

  

  # preserve timestamps (cicku)

  sed -i -e '/install -m/s/-m/-p -m/' Makefile
@@ -61,6 +150,11 @@ 

  

  %ldconfig_scriptlets

  

+ %check

+ 

+ # Don't fail the build on a check failure.

+ make check || true

+ 

  %files

  %license COPYRIGHT

  %doc README
@@ -77,6 +171,11 @@ 

  %{_libdir}/pkgconfig/%{name}.pc

  

  %changelog

+ * Fri Apr 12 2019 Siddhesh Poyarekar <sid@reserved-bit.com> - 2.1.0-0.10beta3

+ - Add upstream bug fixes from the v2.1 branch.

+ - Add bug fixes from https://github.com/siddhesh/LuaJIT.git

+ - Incorporate tests and benchmarks from LuaJIT-test-cleanup.

+ 

  * Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.0-0.9beta3

  - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild

  

LuaJIT has not seen a release for almost 2 years and the maintenance of the project upstream has slowed down. There are however fixes that are suitable for incorporation into Fedora. Additionally, since the upstream maintainer has been largely dormant, a number of patches have gone unreviewed and a major subproject (the LuaJIT-test-cleanup project) stalled. I am collating those patches in my github fork:

https://github.com/siddhesh/LuaJIT/tree/v2.1

and will remain in sync with the upstream project in case there are fixes in there.

This PR has two commits for clarity. The first commit has 59 patches that went into upstream LuaJIT after the 2.1.0-beta3 tag. The second commit has the remaining patches with fixes that have not been (and will likely never be) reviewed upstream.

The second commit also adds the testsuite that is run in the %check target. Tests are currently failing for armv7hl and i686 and pass cleanly for x86_64 and aarch64.

Pull-Request has been merged by ignatenkobrain

5 years ago
Metadata
Changes Summary 73
+31
file added
0001-Fix-LJ_MAX_JSLOTS-assertion-in-rec_check_slots.patch
+40
file added
0002-Add-missing-LJ_MAX_JSLOTS-check.patch
+30
file added
0003-MIPS-Use-precise-search-for-exit-jump-patching.patch
+77
file added
0004-MIPS-Fix-handling-of-spare-long-range-jump-slots.patch
+982
file added
0005-MIPS64-Add-soft-float-support-to-JIT-compiler-backen.patch
+26
file added
0006-FreeBSD-x64-Avoid-changing-resource-limits-if-not-ne.patch
+28
file added
0007-Remove-unused-define.patch
+33
file added
0008-Modify-fix-for-warning-from-ar.patch
+47
file added
0009-x64-LJ_GC64-Fix-emit_rma.patch
+2761
file added
0010-PPC-Add-soft-float-support-to-interpreter.patch
+25
file added
0011-Use-https-for-freelists.org-links.patch
+25
file added
0012-x64-LJ_GC64-Fix-fallback-case-of-asm_fuseloadk64.patch
+751
file added
0013-PPC-Add-soft-float-support-to-JIT-compiler-backend.patch
+26
file added
0014-x64-LJ_GC64-Fix-type-check-only-variant-of-SLOAD.patch
+26
file added
0015-MIPS64-Hide-internal-function.patch
+34
file added
0016-DynASM-x86-Fix-potential-REL_A-overflow.patch
+29
file added
0017-LJ_GC64-Fix-ir_khash-for-non-string-GCobj.patch
+57
file added
0018-LJ_GC64-Make-ASMREF_L-references-64-bit.patch
+26
file added
0019-Fix-FOLD-rule-for-strength-reduction-of-widening.patch
+45
file added
0020-ARM64-Fix-assembly-of-HREFK.patch
+81
file added
0021-MIPS64-Fix-register-allocation-in-assembly-of-HREF.patch
+31
file added
0022-ARM64-Fix-xpcall-error-case.patch
+26
file added
0023-Fix-saved-bytecode-encapsulated-in-ELF-objects.patch
+37
file added
0024-ARM64-Fix-xpcall-error-case-really.patch
+39
file added
0025-MIPS64-Fix-xpcall-error-case.patch
+44
file added
0026-Fix-IR_BUFPUT-assembly.patch
+15
file added
0027-Fix-string.format-c-0.patch
+26
file added
0028-Fix-ARMv8-32-bit-subset-detection.patch
+28
file added
0029-Fix-LuaJIT-API-docs-for-LUAJIT_MODE_.patch
+26
file added
0030-MIPS64-Fix-soft-float-0.0-vs.-0.0-comparison.patch
+69
file added
0031-FFI-Don-t-assert-on-1LL-5.2-compatibility-mode-only.patch
+291
file added
0032-Fix-GCC-7-Wimplicit-fallthrough-warnings.patch
+32
file added
0033-Clear-stack-after-print_jit_status-in-CLI.patch
+52
file added
0034-Fix-rechaining-of-pseudo-resurrected-string-keys.patch
+50
file added
0035-DynASM-x86-Add-BMI1-and-BMI2-instructions.patch
+55
file added
0036-Give-expected-results-for-negative-non-base-10-numbe.patch
+27
file added
0037-FFI-Add-tonumber-specialization-for-failed-conversio.patch
+387
file added
0038-Bump-copyright-date-to-2018.patch
+52
file added
0039-FFI-Make-FP-to-U64-conversions-match-JIT-backend-beh.patch
+33
file added
0040-x86-x64-Check-for-jcc-when-using-xor-r-r-in-emit_loa.patch
+33
file added
0041-PPC-NetBSD-Fix-endianess-check.patch
+91
file added
0042-DynASM-x86-Add-FMA3-instructions.patch
+69
file added
0043-x86-Disassemble-FMA3-instructions.patch
+49
file added
0044-From-Lua-5.3-assert-accepts-any-type-of-error-object.patch
+359
file added
0045-Windows-Add-UWP-support-part-1.patch
+26
file added
0046-ARM64-Fix-write-barrier-in-BC_USETS.patch
+238
file added
0047-ARM64-Fix-exit-stub-patching.patch
+24
file added
0048-DynASM-Fix-warning.patch
+28
file added
0049-DynASM-x86-Fix-vroundps-vroundpd-encoding.patch
+27
file added
0050-Fix-memory-probing-allocator-to-check-for-valid-end-.patch
+39
file added
0051-MIPS-MIPS64-Fix-TSETR-barrier-again.patch
+29
file added
0052-Actually-implement-maxirconst-trace-limit.patch
+27
file added
0053-Better-detection-of-MinGW-build.patch
+131
file added
0054-Fix-overflow-of-snapshot-map-offset.patch
+31
file added
0055-DynASM-PPC-Fix-shadowed-variable.patch
+31
file added
0056-DynASM-MIPS-Fix-shadowed-variable.patch
+26
file added
0057-Fix-MinGW-build.patch
+32
file added
0058-Fix-os.date-for-wider-libc-strftime-compatibility.patch
+35
file added
0059-Improve-luaL_addlstring.patch
+34
file added
0060-Fix-arm64-register-allocation-issue-for-XLOAD.patch
+59
file added
0061-Fix-arm64-register-allocation-issue-for-XLOAD.patch
+50
file added
0062-Remove-redundant-emit_check_ofs.patch
+73
file added
0063-aarch64-Use-the-xzr-register-whenever-possible.patch
+188676
file added
0064-Merge-in-LuaJIT-test-cleanup-into-the-main-repo.patch
+62
file added
0065-Add-support-for-FNMADD-and-FNMSUB.patch
+36
file added
0066-Fix-os.date-for-timezone-change-awareness.patch
+56
file added
0067-Revert-FFI-Make-FP-to-U64-conversions-match-JIT-back.patch
+47
file added
0068-bench-Fix-build-warnings.patch
+42
file added
0069-Guard-against-undefined-behaviour-when-casting-from-.patch
+25
file added
0070-Fix-build-erro-with-fnmsub-fusing.patch
+77
file added
0071-aarch64-better-float-to-unsigned-int-conversion.patch
+39
file added
0072-Better-behaviour-for-float-to-uint32_t-conversions.patch
+101 -2
file changed
luajit.spec