aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildvm.c7
-rw-r--r--src/buildvm.h1
-rw-r--r--src/buildvm_fold.c8
-rw-r--r--src/lj_asm.c2
-rw-r--r--src/lj_crecord.c31
-rw-r--r--src/lj_ir.h12
-rw-r--r--src/lj_opt_fold.c10
7 files changed, 45 insertions, 26 deletions
diff --git a/src/buildvm.c b/src/buildvm.c
index 1681b592..8c127d45 100644
--- a/src/buildvm.c
+++ b/src/buildvm.c
@@ -253,6 +253,13 @@ IRDEF(IRNAME)
253 NULL 253 NULL
254}; 254};
255 255
256const char *const irt_names[] = {
257#define IRTNAME(name) #name,
258IRTDEF(IRTNAME)
259#undef IRTNAME
260 NULL
261};
262
256const char *const irfpm_names[] = { 263const char *const irfpm_names[] = {
257#define FPMNAME(name) #name, 264#define FPMNAME(name) #name,
258IRFPMDEF(FPMNAME) 265IRFPMDEF(FPMNAME)
diff --git a/src/buildvm.h b/src/buildvm.h
index 27a0a842..0d1d32ad 100644
--- a/src/buildvm.h
+++ b/src/buildvm.h
@@ -96,6 +96,7 @@ extern void emit_fold(BuildCtx *ctx);
96 96
97extern const char *const bc_names[]; 97extern const char *const bc_names[];
98extern const char *const ir_names[]; 98extern const char *const ir_names[];
99extern const char *const irt_names[];
99extern const char *const irfpm_names[]; 100extern const char *const irfpm_names[];
100extern const char *const irfield_names[]; 101extern const char *const irfield_names[];
101extern const char *const ircall_names[]; 102extern const char *const ircall_names[];
diff --git a/src/buildvm_fold.c b/src/buildvm_fold.c
index eaca067f..468e5300 100644
--- a/src/buildvm_fold.c
+++ b/src/buildvm_fold.c
@@ -110,6 +110,14 @@ static uint32_t nexttoken(char **pp, int allowlit, int allowany)
110 for (i = 0; ircall_names[i]; i++) 110 for (i = 0; ircall_names[i]; i++)
111 if (!strcmp(ircall_names[i], p+7)) 111 if (!strcmp(ircall_names[i], p+7))
112 return i; 112 return i;
113 } else if (allowlit && !strncmp(p, "IRCONV_", 7)) {
114 for (i = 0; irt_names[i]; i++)
115 if (!strncmp(irt_names[i], p+7, 3) && p[10] == '_') {
116 uint32_t j;
117 for (j = 0; irt_names[j]; j++)
118 if (!strncmp(irt_names[j], p+11, 3))
119 return (i << 5) + j;
120 }
113 } else if (allowlit && *p >= '0' && *p <= '9') { 121 } else if (allowlit && *p >= '0' && *p <= '9') {
114 for (i = 0; *p >= '0' && *p <= '9'; p++) 122 for (i = 0; *p >= '0' && *p <= '9'; p++)
115 i = i*10 + (*p - '0'); 123 i = i*10 + (*p - '0');
diff --git a/src/lj_asm.c b/src/lj_asm.c
index eb6f00e7..9009a7d5 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1656,7 +1656,7 @@ static void asm_toi64(ASMState *as, IRIns *ir)
1656 1656
1657static void asm_conv(ASMState *as, IRIns *ir) 1657static void asm_conv(ASMState *as, IRIns *ir)
1658{ 1658{
1659 IRType st = (IRType)(ir->op2 & 0x1f); 1659 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
1660 int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64)); 1660 int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64));
1661 int stfp = (st == IRT_NUM || st == IRT_FLOAT); 1661 int stfp = (st == IRT_NUM || st == IRT_FLOAT);
1662 IRRef lref = ir->op1; 1662 IRRef lref = ir->op1;
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 5844b9ed..23b92831 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -29,6 +29,9 @@
29/* Pass IR on to next optimization in chain (FOLD). */ 29/* Pass IR on to next optimization in chain (FOLD). */
30#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) 30#define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
31 31
32#define emitconv(a, dt, st, flags) \
33 emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags))
34
32/* -- C type checks ------------------------------------------------------- */ 35/* -- C type checks ------------------------------------------------------- */
33 36
34static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o) 37static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
@@ -145,15 +148,14 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
145#if LJ_64 148#if LJ_64
146 /* Sign-extend 32 to 64 bit integer. */ 149 /* Sign-extend 32 to 64 bit integer. */
147 if (dsize == 8 && ssize < 8 && !(sinfo & CTF_UNSIGNED)) 150 if (dsize == 8 && ssize < 8 && !(sinfo & CTF_UNSIGNED))
148 sp = emitir(IRT(IR_CONV, dt), sp, IRT_INT|IRCONV_SEXT); 151 sp = emitconv(sp, dt, IRT_INT, IRCONV_SEXT);
149 /* All other conversions are no-ops on x64. */ 152 /* All other conversions are no-ops on x64. */
150#else 153#else
151 if (dsize == 8 && ssize < 8) /* Extend to 64 bit integer. */ 154 if (dsize == 8 && ssize < 8) /* Extend to 64 bit integer. */
152 sp = emitir(IRT(IR_CONV, dt), sp, 155 sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st,
153 (st < IRT_INT ? IRT_INT : st) | 156 (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
154 ((sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT));
155 else if (dsize < 8 && ssize == 8) /* Truncate from 64 bit integer. */ 157 else if (dsize < 8 && ssize == 8) /* Truncate from 64 bit integer. */
156 sp = emitir(IRT(IR_CONV, dt < IRT_INT ? IRT_INT : dt), sp, st); 158 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0);
157#endif 159#endif
158 xstore: 160 xstore:
159 emitir(IRT(IR_XSTORE, dt), dp, sp); 161 emitir(IRT(IR_XSTORE, dt), dp, sp);
@@ -163,7 +165,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
163 /* fallthrough */ 165 /* fallthrough */
164 case CCX(I, F): 166 case CCX(I, F):
165 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; 167 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
166 sp = emitir(IRT(IR_CONV, dsize < 4 ? IRT_INT : dt), sp, st|IRCONV_TRUNC); 168 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC);
167 goto xstore; 169 goto xstore;
168 case CCX(I, P): 170 case CCX(I, P):
169 case CCX(I, A): 171 case CCX(I, A):
@@ -177,7 +179,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
177 case CCX(F, I): 179 case CCX(F, I):
178 conv_F_I: 180 conv_F_I:
179 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; 181 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
180 sp = emitir(IRT(IR_CONV, dt), sp, st < IRT_INT ? IRT_INT : st); 182 sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0);
181 goto xstore; 183 goto xstore;
182 case CCX(F, C): 184 case CCX(F, C):
183 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */ 185 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
@@ -185,7 +187,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
185 case CCX(F, F): 187 case CCX(F, F):
186 conv_F_F: 188 conv_F_F:
187 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; 189 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
188 if (dt != st) sp = emitir(IRT(IR_CONV, dt), sp, st); 190 if (dt != st) sp = emitconv(sp, dt, st, 0);
189 goto xstore; 191 goto xstore;
190 192
191 /* Destination is a complex number. */ 193 /* Destination is a complex number. */
@@ -206,8 +208,8 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
206 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1))); 208 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
207 im = emitir(IRT(IR_XLOAD, st), ptr, 0); 209 im = emitir(IRT(IR_XLOAD, st), ptr, 0);
208 if (dt != st) { 210 if (dt != st) {
209 re = emitir(IRT(IR_CONV, dt), re, st); 211 re = emitconv(re, dt, st, 0);
210 im = emitir(IRT(IR_CONV, dt), im, st); 212 im = emitconv(im, dt, st, 0);
211 } 213 }
212 emitir(IRT(IR_XSTORE, dt), dp, re); 214 emitir(IRT(IR_XSTORE, dt), dp, re);
213 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1))); 215 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
@@ -233,13 +235,13 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
233 case CCX(P, I): 235 case CCX(P, I):
234 if (st == IRT_CDATA) goto err_nyi; 236 if (st == IRT_CDATA) goto err_nyi;
235 if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */ 237 if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */
236 sp = emitir(IRT(IR_CONV, IRT_U32), sp, st); 238 sp = emitconv(sp, IRT_U32, st, 0);
237 goto xstore; 239 goto xstore;
238 case CCX(P, F): 240 case CCX(P, F):
239 if (st == IRT_CDATA) goto err_nyi; 241 if (st == IRT_CDATA) goto err_nyi;
240 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ 242 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
241 sp = emitir(IRT(IR_CONV, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32), 243 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
242 sp, st|IRCONV_TRUNC); 244 st, IRCONV_TRUNC);
243 goto xstore; 245 goto xstore;
244 246
245 /* Destination is an array. */ 247 /* Destination is an array. */
@@ -274,7 +276,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
274 goto err_nyi; /* NYI: copyval of >64 bit integers. */ 276 goto err_nyi; /* NYI: copyval of >64 bit integers. */
275 tr = emitir(IRT(IR_XLOAD, t), sp, 0); 277 tr = emitir(IRT(IR_XLOAD, t), sp, 0);
276 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */ 278 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */
277 tr = emitir(IRT(IR_CONV, IRT_NUM), tr, t); 279 tr = emitconv(tr, IRT_NUM, t, 0);
278 } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */ 280 } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */
279 TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); 281 TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
280 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, 282 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp,
@@ -567,5 +569,6 @@ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
567 569
568#undef IR 570#undef IR
569#undef emitir 571#undef emitir
572#undef emitconv
570 573
571#endif 574#endif
diff --git a/src/lj_ir.h b/src/lj_ir.h
index 75635f93..a6d36283 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -219,11 +219,13 @@ IRFLDEF(FLENUM)
219#define IRTOINT_TRUNCI64 5 /* Truncate number to int64_t. */ 219#define IRTOINT_TRUNCI64 5 /* Truncate number to int64_t. */
220#define IRTOINT_TOBIT 6 /* Cache only: TOBIT conversion. */ 220#define IRTOINT_TOBIT 6 /* Cache only: TOBIT conversion. */
221 221
222/* CONV mode, stored in op2. Lowest 8 bits is the IRType of the source. */ 222/* CONV mode, stored in op2. */
223#define IRCONV_TRUNC 0x100 /* Truncate number to integer. */ 223#define IRCONV_SRCMASK 0x001f /* Source IRType. */
224#define IRCONV_SEXT 0x200 /* Sign-extend integer to integer. */ 224#define IRCONV_DSTMASK 0x03e0 /* Dest. IRType (also in ir->t). */
225#define IRCONV_MODEMASK 0x3ff 225#define IRCONV_TRUNC 0x0400 /* Truncate number to integer. */
226#define IRCONV_CSH 10 226#define IRCONV_SEXT 0x0800 /* Sign-extend integer to integer. */
227#define IRCONV_MODEMASK 0x0fff
228#define IRCONV_CSH 12
227/* Number to integer conversion mode. Ordered by strength of the checks. */ 229/* Number to integer conversion mode. Ordered by strength of the checks. */
228#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */ 230#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */
229#define IRCONV_ANY (1<<IRCONV_CSH) /* Any FP number is ok. */ 231#define IRCONV_ANY (1<<IRCONV_CSH) /* Any FP number is ok. */
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 8f05e7c8..4790d245 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -781,11 +781,9 @@ LJFOLDF(cse_conv)
781 IRRef ref = J->chain[IR_CONV]; 781 IRRef ref = J->chain[IR_CONV];
782 while (ref > op1) { 782 while (ref > op1) {
783 IRIns *ir = IR(ref); 783 IRIns *ir = IR(ref);
784 /* CSE also depends on the target type! 784 /* Commoning with stronger checks is ok. */
785 ** OTOH commoning with stronger checks is ok, too. 785 if (ir->op1 == op1 && (ir->op2 & IRCONV_MODEMASK) == op2 &&
786 */ 786 irt_isguard(ir->t) >= guard)
787 if (ir->op1 == op1 && irt_sametype(ir->t, fins->t) &&
788 (ir->op2 & IRCONV_MODEMASK) == op2 && irt_isguard(ir->t) >= guard)
789 return ref; 787 return ref;
790 ref = ir->prev; 788 ref = ir->prev;
791 } 789 }
@@ -1773,7 +1771,7 @@ retry:
1773 key += (uint32_t)IR(fins->op2)->o; 1771 key += (uint32_t)IR(fins->op2)->o;
1774 *fright = *IR(fins->op2); 1772 *fright = *IR(fins->op2);
1775 } else { 1773 } else {
1776 key += (fins->op2 & 0xffu); /* For IRFPM_* and IRFL_*. */ 1774 key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */
1777 } 1775 }
1778 1776
1779 /* Check for a match in order from most specific to least specific. */ 1777 /* Check for a match in order from most specific to least specific. */