Copy destination type for CONV from ir->t to op2, too.
This commit is contained in:
parent
dc4b82c33d
commit
65b194a2f8
@ -238,9 +238,10 @@ local litname = {
|
||||
["XLOAD "] = { [0] = "", "R", "U", "RU", },
|
||||
["CONV "] = setmetatable({}, { __index = function(t, mode)
|
||||
local s = irtype[band(mode, 31)]
|
||||
if band(mode, 0x100) ~= 0 then s = s.." trunc"
|
||||
elseif band(mode, 0x200) ~= 0 then s = s.." sext" end
|
||||
local c = shr(mode, 10)
|
||||
s = irtype[band(shr(mode, 5), 31)].."."..s
|
||||
if band(mode, 0x400) ~= 0 then s = s.." trunc"
|
||||
elseif band(mode, 0x800) ~= 0 then s = s.." sext" end
|
||||
local c = shr(mode, 14)
|
||||
if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
|
||||
t[mode] = s
|
||||
return s
|
||||
|
@ -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)
|
||||
|
@ -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[];
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
12
src/lj_ir.h
12
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<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */
|
||||
#define IRCONV_ANY (1<<IRCONV_CSH) /* Any FP number is ok. */
|
||||
|
@ -781,11 +781,9 @@ LJFOLDF(cse_conv)
|
||||
IRRef ref = J->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. */
|
||||
|
Loading…
Reference in New Issue
Block a user