Parcourir la source

DUALNUM: Improve/fix edge cases of unary minus.

Thanks to Sergey Kaplun. #1422 #1418
Mike Pall il y a 2 semaines
Parent
commit
707c12bf00
8 fichiers modifiés avec 33 ajouts et 7 suppressions
  1. 2 3
      src/lj_opt_narrow.c
  2. 4 1
      src/vm_arm.dasc
  3. 2 0
      src/vm_arm64.dasc
  4. 5 1
      src/vm_mips.dasc
  5. 5 1
      src/vm_mips64.dasc
  6. 6 1
      src/vm_ppc.dasc
  7. 4 0
      src/vm_x64.dasc
  8. 5 0
      src/vm_x86.dasc

+ 2 - 3
src/lj_opt_narrow.c

@@ -545,10 +545,9 @@ TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc)
   rc = conv_str_tonum(J, rc, vc);
   if (tref_isinteger(rc)) {
     uint32_t k = (uint32_t)numberVint(vc);
-    if ((tvisint(vc) || k != 0) && k != 0x80000000u) {
+    if (k != 0 && k != 0x80000000u) {
       TRef zero = lj_ir_kint(J, 0);
-      if (!tvisint(vc))
-	emitir(IRTGI(IR_NE), rc, zero);
+      emitir(IRTGI(IR_NE), rc, zero);
       return emitir(IRTGI(IR_SUBOV), zero, rc);
     }
     rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);

+ 4 - 1
src/vm_arm.dasc

@@ -3125,13 +3125,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  bhi ->vmeta_unm
     |  eorne CARG2, CARG2, #0x80000000
     |  bne >5
-    |  rsbseq CARG1, CARG1, #0
+    |  rsbs CARG1, CARG1, #0
+    |  ldrdeq CARG12, >8
     |  ldrdvs CARG12, >9
     |5:
     |  strd CARG12, [BASE, RA]
     |   ins_next3
     |
     |.align 8
+    |8:
+    |  .long 0x00000000, 0x80000000	// -0.
     |9:
     |  .long 0x00000000, 0x41e00000	// 2^31.
     break;

+ 2 - 0
src/vm_arm64.dasc

@@ -2687,6 +2687,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   movz CARG3, #0x41e0, lsl #48	// 2^31.
     |   add_TISNUM TMP0, TMP0
     |  csel TMP0, TMP0, CARG3, vc
+    |   movz CARG3, #0x8000, lsl #48	// -0.
+    |  csel TMP0, TMP0, CARG3, ne
     |5:
     |  str TMP0, [BASE, RA, lsl #3]
     |  ins_next

+ 5 - 1
src/vm_mips.dasc

@@ -3566,7 +3566,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   addu RA, BASE, RA
     |  bne SFARG1HI, TISNUM, >2
     |.  lw SFARG1LO, LO(RB)
-    |  lui TMP1, 0x8000
+    |  beqz SFARG1LO, >3
+    |.  lui TMP1, 0x8000
     |  beq SFARG1LO, TMP1, ->vmeta_unm	// Meta handler deals with -2^31.
     |.  negu SFARG1LO, SFARG1LO
     |1:
@@ -3580,6 +3581,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.  lui TMP1, 0x8000
     |  b <1
     |.  xor SFARG1HI, SFARG1HI, TMP1
+    |3:
+    |  b <1
+    |.  lui SFARG1HI, 0x8000	// -0.
     break;
   case BC_LEN:
     |  // RA = dst*8, RD = src*8

+ 5 - 1
src/vm_mips64.dasc

@@ -3804,7 +3804,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  sextw CARG1, CARG1
     |  beq CARG1, TMP1, ->vmeta_unm	// Meta handler deals with -2^31.
     |.  negu CARG1, CARG1
-    |  zextw CARG1, CARG1
+    |  beqz CARG1, >3
+    |.  zextw CARG1, CARG1
     |  settp CARG1, TISNUM
     |1:
     |  ins_next1
@@ -3816,6 +3817,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.  dsll TMP1, TMP1, 32
     |  b <1
     |.  xor CARG1, CARG1, TMP1
+    |3:
+    |  b <1
+    |.  dsll CARG1, TMP1, 32
     break;
   case BC_LEN:
     |  // RA = dst*8, RD = src*8

+ 6 - 1
src/vm_ppc.dasc

@@ -3962,11 +3962,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  bne >5
     |.if GPR64
     |  lus TMP2, 0x8000
-    |  neg TMP0, TMP0
+    |  neg. TMP0, TMP0
+    |  beq >8
     |  cmplw TMP0, TMP2
     |  beq >4
     |.else
     |  nego. TMP0, TMP0
+    |  beq >8
     |  bso >4
     |1:
     |.endif
@@ -3993,6 +3995,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |   stw TMP0, 4(RA)
     |.if DUALNUM
     |  b <3
+    |8:
+    |  lus TMP1, 0x8000			// -0.
+    |  b <7
     |.else
     |  ins_next2
     |.endif

+ 4 - 0
src/vm_x64.dasc

@@ -3266,11 +3266,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |.if DUALNUM
     |  checkint RB, >5
     |  neg RBd
+    |  jz >3
     |  jo >4
     |  setint RB
     |9:
     |  mov [BASE+RA*8], RB
     |  ins_next
+    |3:
+    |  mov64 RB, U64x(80000000,00000000)  // -0.
+    |  jmp <9
     |4:
     |  mov64 RB, U64x(41e00000,00000000)  // 2^31.
     |  jmp <9

+ 5 - 0
src/vm_x86.dasc

@@ -3856,11 +3856,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     |  checkint RD, >5
     |  mov RB, [BASE+RD*8]
     |  neg RB
+    |  jz >3
     |  jo >4
     |  mov dword [BASE+RA*8+4], LJ_TISNUM
+    |8:
     |  mov dword [BASE+RA*8], RB
     |9:
     |  ins_next
+    |3:
+    |  mov dword [BASE+RA*8+4], 0x80000000  // -0.
+    |  jmp <8
     |4:
     |  mov dword [BASE+RA*8+4], 0x41e00000  // 2^31.
     |  mov dword [BASE+RA*8], 0