From 65b194a2f89eb315029724af56354bb527021192 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Fri, 31 Dec 2010 01:00:54 +0100 Subject: Copy destination type for CONV from ir->t to op2, too. --- src/buildvm.c | 7 +++++++ src/buildvm.h | 1 + src/buildvm_fold.c | 8 ++++++++ src/lj_asm.c | 2 +- src/lj_crecord.c | 31 +++++++++++++++++-------------- src/lj_ir.h | 12 +++++++----- src/lj_opt_fold.c | 10 ++++------ 7 files changed, 45 insertions(+), 26 deletions(-) (limited to 'src') 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) NULL }; +const char *const irt_names[] = { +#define IRTNAME(name) #name, +IRTDEF(IRTNAME) +#undef IRTNAME + NULL +}; + const char *const irfpm_names[] = { #define FPMNAME(name) #name, IRFPMDEF(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); extern const char *const bc_names[]; extern const char *const ir_names[]; +extern const char *const irt_names[]; extern const char *const irfpm_names[]; extern const char *const irfield_names[]; extern 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) for (i = 0; ircall_names[i]; i++) if (!strcmp(ircall_names[i], p+7)) return i; + } else if (allowlit && !strncmp(p, "IRCONV_", 7)) { + for (i = 0; irt_names[i]; i++) + if (!strncmp(irt_names[i], p+7, 3) && p[10] == '_') { + uint32_t j; + for (j = 0; irt_names[j]; j++) + if (!strncmp(irt_names[j], p+11, 3)) + return (i << 5) + j; + } } else if (allowlit && *p >= '0' && *p <= '9') { for (i = 0; *p >= '0' && *p <= '9'; p++) 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) static void asm_conv(ASMState *as, IRIns *ir) { - IRType st = (IRType)(ir->op2 & 0x1f); + IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64)); int stfp = (st == IRT_NUM || st == IRT_FLOAT); 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 @@ /* Pass IR on to next optimization in chain (FOLD). */ #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) +#define emitconv(a, dt, st, flags) \ + emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags)) + /* -- C type checks ------------------------------------------------------- */ static 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) #if LJ_64 /* Sign-extend 32 to 64 bit integer. */ if (dsize == 8 && ssize < 8 && !(sinfo & CTF_UNSIGNED)) - sp = emitir(IRT(IR_CONV, dt), sp, IRT_INT|IRCONV_SEXT); + sp = emitconv(sp, dt, IRT_INT, IRCONV_SEXT); /* All other conversions are no-ops on x64. */ #else if (dsize == 8 && ssize < 8) /* Extend to 64 bit integer. */ - sp = emitir(IRT(IR_CONV, dt), sp, - (st < IRT_INT ? IRT_INT : st) | - ((sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT)); + sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, + (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); else if (dsize < 8 && ssize == 8) /* Truncate from 64 bit integer. */ - sp = emitir(IRT(IR_CONV, dt < IRT_INT ? IRT_INT : dt), sp, st); + sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0); #endif xstore: 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) /* fallthrough */ case CCX(I, F): if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; - sp = emitir(IRT(IR_CONV, dsize < 4 ? IRT_INT : dt), sp, st|IRCONV_TRUNC); + sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC); goto xstore; case CCX(I, P): case CCX(I, A): @@ -177,7 +179,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp) case CCX(F, I): conv_F_I: if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; - sp = emitir(IRT(IR_CONV, dt), sp, st < IRT_INT ? IRT_INT : st); + sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0); goto xstore; case CCX(F, C): 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) case CCX(F, F): conv_F_F: if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; - if (dt != st) sp = emitir(IRT(IR_CONV, dt), sp, st); + if (dt != st) sp = emitconv(sp, dt, st, 0); goto xstore; /* 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) ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1))); im = emitir(IRT(IR_XLOAD, st), ptr, 0); if (dt != st) { - re = emitir(IRT(IR_CONV, dt), re, st); - im = emitir(IRT(IR_CONV, dt), im, st); + re = emitconv(re, dt, st, 0); + im = emitconv(im, dt, st, 0); } emitir(IRT(IR_XSTORE, dt), dp, re); 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) case CCX(P, I): if (st == IRT_CDATA) goto err_nyi; if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */ - sp = emitir(IRT(IR_CONV, IRT_U32), sp, st); + sp = emitconv(sp, IRT_U32, st, 0); goto xstore; case CCX(P, F): if (st == IRT_CDATA) goto err_nyi; /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ - sp = emitir(IRT(IR_CONV, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32), - sp, st|IRCONV_TRUNC); + sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32, + st, IRCONV_TRUNC); goto xstore; /* Destination is an array. */ @@ -274,7 +276,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) goto err_nyi; /* NYI: copyval of >64 bit integers. */ tr = emitir(IRT(IR_XLOAD, t), sp, 0); if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */ - tr = emitir(IRT(IR_CONV, IRT_NUM), tr, t); + tr = emitconv(tr, IRT_NUM, t, 0); } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */ TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, @@ -567,5 +569,6 @@ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) #undef IR #undef emitir +#undef emitconv #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) #define IRTOINT_TRUNCI64 5 /* Truncate number to int64_t. */ #define IRTOINT_TOBIT 6 /* Cache only: TOBIT conversion. */ -/* CONV mode, stored in op2. Lowest 8 bits is the IRType of the source. */ -#define IRCONV_TRUNC 0x100 /* Truncate number to integer. */ -#define IRCONV_SEXT 0x200 /* Sign-extend integer to integer. */ -#define IRCONV_MODEMASK 0x3ff -#define IRCONV_CSH 10 +/* CONV mode, stored in op2. */ +#define IRCONV_SRCMASK 0x001f /* Source IRType. */ +#define IRCONV_DSTMASK 0x03e0 /* Dest. IRType (also in ir->t). */ +#define IRCONV_TRUNC 0x0400 /* Truncate number to integer. */ +#define IRCONV_SEXT 0x0800 /* Sign-extend integer to integer. */ +#define IRCONV_MODEMASK 0x0fff +#define IRCONV_CSH 12 /* Number to integer conversion mode. Ordered by strength of the checks. */ #define IRCONV_TOBIT (0<chain[IR_CONV]; while (ref > op1) { IRIns *ir = IR(ref); - /* CSE also depends on the target type! - ** OTOH commoning with stronger checks is ok, too. - */ - if (ir->op1 == op1 && irt_sametype(ir->t, fins->t) && - (ir->op2 & IRCONV_MODEMASK) == op2 && irt_isguard(ir->t) >= guard) + /* Commoning with stronger checks is ok. */ + if (ir->op1 == op1 && (ir->op2 & IRCONV_MODEMASK) == op2 && + irt_isguard(ir->t) >= guard) return ref; ref = ir->prev; } @@ -1773,7 +1771,7 @@ retry: key += (uint32_t)IR(fins->op2)->o; *fright = *IR(fins->op2); } else { - key += (fins->op2 & 0xffu); /* For IRFPM_* and IRFL_*. */ + key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */ } /* Check for a match in order from most specific to least specific. */ -- cgit v1.2.3-55-g6feb