aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_cconv.c3
-rw-r--r--src/lj_crecord.c149
-rw-r--r--src/lj_ir.h2
3 files changed, 82 insertions, 72 deletions
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
index e5abf3e9..642a4852 100644
--- a/src/lj_cconv.c
+++ b/src/lj_cconv.c
@@ -335,7 +335,8 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
335 335
336 case CCX(P, F): 336 case CCX(P, F):
337 if (!(flags & CCF_CAST) || !(flags & CCF_FROMTV)) goto err_conv; 337 if (!(flags & CCF_CAST) || !(flags & CCF_FROMTV)) goto err_conv;
338 dinfo = CTINFO(CT_NUM, CTF_UNSIGNED); 338 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
339 dinfo = CTINFO(CT_NUM, (LJ_64 && dsize == 8) ? 0 : CTF_UNSIGNED);
339 goto conv_I_F; 340 goto conv_I_F;
340 341
341 case CCX(P, P): 342 case CCX(P, P):
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 326ff6de..5844b9ed 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -90,8 +90,10 @@ static IRType crec_ct2irt(CType *ct)
90{ 90{
91 if (LJ_LIKELY(ctype_isnum(ct->info))) { 91 if (LJ_LIKELY(ctype_isnum(ct->info))) {
92 if ((ct->info & CTF_FP)) { 92 if ((ct->info & CTF_FP)) {
93 if (ct->size == sizeof(double)) /* NYI: float IRType. */ 93 if (ct->size == sizeof(double))
94 return IRT_NUM; 94 return IRT_NUM;
95 else if (ct->size == sizeof(float))
96 return IRT_FLOAT;
95 } else { 97 } else {
96 uint32_t b = lj_fls(ct->size); 98 uint32_t b = lj_fls(ct->size);
97 if (b <= 3) 99 if (b <= 3)
@@ -99,16 +101,21 @@ static IRType crec_ct2irt(CType *ct)
99 } 101 }
100 } else if (ctype_isptr(ct->info)) { 102 } else if (ctype_isptr(ct->info)) {
101 return (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; 103 return (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
104 } else if (ctype_iscomplex(ct->info)) {
105 if (ct->size == 2*sizeof(double))
106 return IRT_NUM;
107 else if (ct->size == 2*sizeof(float))
108 return IRT_FLOAT;
102 } 109 }
103 return IRT_CDATA; 110 return IRT_CDATA;
104} 111}
105 112
106static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp) 113static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
107{ 114{
108 CTState *cts = ctype_ctsG(J2G(J));
109 CTSize dsize = d->size, ssize = s->size; 115 CTSize dsize = d->size, ssize = s->size;
110 CTInfo dinfo = d->info, sinfo = s->info; 116 CTInfo dinfo = d->info, sinfo = s->info;
111 IRType dt = crec_ct2irt(d); 117 IRType dt = crec_ct2irt(d);
118 IRType st = crec_ct2irt(s);
112 119
113 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT) 120 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
114 goto err_conv; 121 goto err_conv;
@@ -134,90 +141,77 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
134 case CCX(I, B): 141 case CCX(I, B):
135 case CCX(I, I): 142 case CCX(I, I):
136 conv_I_I: 143 conv_I_I:
137 lua_assert(ssize >= 4); 144 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
138 if (dsize > 8 || ssize > 8) goto err_nyi; 145#if LJ_64
139 if (dsize > ssize) /* Zero-extend or sign-extend 32 to 64 bit integer. */ 146 /* Sign-extend 32 to 64 bit integer. */
140 sp = emitir(IRT(IR_TOI64, dt), sp, 147 if (dsize == 8 && ssize < 8 && !(sinfo & CTF_UNSIGNED))
141 (sinfo&CTF_UNSIGNED) ? IRTOINT_ZEXT64 : IRTOINT_SEXT64); 148 sp = emitir(IRT(IR_CONV, dt), sp, IRT_INT|IRCONV_SEXT);
149 /* All other conversions are no-ops on x64. */
150#else
151 if (dsize == 8 && ssize < 8) /* Extend to 64 bit integer. */
152 sp = emitir(IRT(IR_CONV, dt), sp,
153 (st < IRT_INT ? IRT_INT : st) |
154 ((sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT));
155 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);
157#endif
142 xstore: 158 xstore:
143 emitir(IRT(IR_XSTORE, dt), dp, sp); 159 emitir(IRT(IR_XSTORE, dt), dp, sp);
144 break; 160 break;
161 case CCX(I, C):
162 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
163 /* fallthrough */
145 case CCX(I, F): 164 case CCX(I, F):
146 conv_I_F: 165 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
147 if (dsize > 8 || ssize != sizeof(double)) goto err_nyi; 166 sp = emitir(IRT(IR_CONV, dsize < 4 ? IRT_INT : dt), sp, st|IRCONV_TRUNC);
148 if (dsize == 8) {
149 if (dt == IRT_U64) goto err_nyi;
150 sp = emitir(IRT(IR_TOI64, dt), sp, IRTOINT_TRUNCI64);
151 } else {
152 sp = emitir(IRTI(IR_TOINT), sp, IRTOINT_ANY); /* NYI: should truncate. */
153 }
154 goto xstore; 167 goto xstore;
155 case CCX(I, C):
156 if (ssize != 2*sizeof(double)) goto err_nyi;
157 sp = emitir(IRT(IR_XLOAD, IRT_NUM), sp, 0); /* Load re. */
158 s = ctype_child(cts, s);
159 sinfo = s->info;
160 ssize = s->size;
161 goto conv_I_F; /* Just convert re. */
162 case CCX(I, P): 168 case CCX(I, P):
163 case CCX(I, A): 169 case CCX(I, A):
164 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED); 170 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
165 ssize = CTSIZE_PTR; 171 ssize = CTSIZE_PTR;
166 /* 172 st = IRT_UINTP;
167 ** Note: Overriding the size is also required for pointers, since
168 ** crec_ct_tv passes IRT_P32/IRT_P64 independently of the C type size.
169 ** This avoids unnecessary zero-extensions on x64.
170 */
171 goto conv_I_I; 173 goto conv_I_I;
172 174
173 /* Destination is a floating-point number. */ 175 /* Destination is a floating-point number. */
174 case CCX(F, B): 176 case CCX(F, B):
175 case CCX(F, I): 177 case CCX(F, I):
176 conv_F_I: 178 conv_F_I:
177 if (dsize != sizeof(double) || ssize > 4) goto err_nyi; 179 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
178 if (ssize == 4 && (sinfo & CTF_UNSIGNED)) goto err_nyi; 180 sp = emitir(IRT(IR_CONV, dt), sp, st < IRT_INT ? IRT_INT : st);
179 sp = emitir(IRTI(IR_TONUM), sp, 0);
180 goto xstore; 181 goto xstore;
182 case CCX(F, C):
183 sp = emitir(IRT(IR_XLOAD, st), sp, 0); /* Load re. */
184 /* fallthrough */
181 case CCX(F, F): 185 case CCX(F, F):
182 conv_F_F: 186 conv_F_F:
183 if (dsize != sizeof(double) || ssize != sizeof(double)) goto err_nyi; 187 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
188 if (dt != st) sp = emitir(IRT(IR_CONV, dt), sp, st);
184 goto xstore; 189 goto xstore;
185 case CCX(F, C):
186 if (ssize != 2*sizeof(double)) goto err_nyi;
187 sp = emitir(IRT(IR_XLOAD, IRT_NUM), sp, 0); /* Load re. */
188 s = ctype_child(cts, s);
189 sinfo = s->info;
190 ssize = s->size;
191 goto conv_F_F; /* Ignore im, and convert from re. */
192 190
193 /* Destination is a complex number. */ 191 /* Destination is a complex number. */
194 case CCX(C, I): 192 case CCX(C, I):
195 case CCX(C, F): 193 case CCX(C, F):
196 d = ctype_child(cts, d);
197 dinfo = d->info;
198 dsize = d->size;
199 dt = crec_ct2irt(d);
200 if (dt == IRT_CDATA) goto err_nyi;
201 { /* Clear im. */ 194 { /* Clear im. */
202 TRef dpim = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, dsize)); 195 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
203 emitir(IRT(IR_XSTORE, IRT_NUM), dpim, lj_ir_knum(J, 0)); 196 emitir(IRT(IR_XSTORE, dt), ptr, lj_ir_knum(J, 0));
204 } 197 }
205 /* Convert to re. */ 198 /* Convert to re. */
206 if ((sinfo & CTF_FP)) goto conv_F_F; else goto conv_F_I; 199 if ((sinfo & CTF_FP)) goto conv_F_F; else goto conv_F_I;
207 200
208 case CCX(C, C): 201 case CCX(C, C):
209 d = ctype_child(cts, d); 202 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
210 dinfo = d->info;
211 dsize = d->size;
212 dt = crec_ct2irt(d);
213 if (dt == IRT_CDATA) goto err_nyi;
214 { 203 {
215 TRef spim = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, dsize)); 204 TRef re, im, ptr;
216 TRef re = emitir(IRT(IR_XLOAD, IRT_NUM), sp, 0); 205 re = emitir(IRT(IR_XLOAD, st), sp, 0);
217 TRef im = emitir(IRT(IR_XLOAD, IRT_NUM), spim, 0); 206 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
218 TRef dpim = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, dsize)); 207 im = emitir(IRT(IR_XLOAD, st), ptr, 0);
219 emitir(IRT(IR_XSTORE, IRT_NUM), dp, re); 208 if (dt != st) {
220 emitir(IRT(IR_XSTORE, IRT_NUM), dpim, im); 209 re = emitir(IRT(IR_CONV, dt), re, st);
210 im = emitir(IRT(IR_CONV, dt), im, st);
211 }
212 emitir(IRT(IR_XSTORE, dt), dp, re);
213 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
214 emitir(IRT(IR_XSTORE, dt), ptr, im);
221 } 215 }
222 break; 216 break;
223 217
@@ -230,19 +224,23 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
230 224
231 /* Destination is a pointer. */ 225 /* Destination is a pointer. */
232 case CCX(P, P): 226 case CCX(P, P):
233 /* Note: ok on x64, since all 32 bit ops clear the upper part of the reg. */
234 goto xstore;
235 case CCX(P, A): 227 case CCX(P, A):
236 case CCX(P, S): 228 case CCX(P, S):
237 ssize = CTSIZE_PTR; 229 /* There are only 32 bit pointers/addresses on 32 bit machines.
238 sinfo = CTINFO(CT_NUM, CTF_UNSIGNED); 230 ** Also ok on x64, since all 32 bit ops clear the upper part of the reg.
239 /* fallthrough */ 231 */
232 goto xstore;
240 case CCX(P, I): 233 case CCX(P, I):
241 dinfo = CTINFO(CT_NUM, CTF_UNSIGNED); 234 if (st == IRT_CDATA) goto err_nyi;
242 goto conv_I_I; 235 if (!LJ_64 && ssize == 8) /* Truncate from 64 bit integer. */
236 sp = emitir(IRT(IR_CONV, IRT_U32), sp, st);
237 goto xstore;
243 case CCX(P, F): 238 case CCX(P, F):
244 dinfo = CTINFO(CT_NUM, CTF_UNSIGNED); 239 if (st == IRT_CDATA) goto err_nyi;
245 goto conv_I_F; 240 /* 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),
242 sp, st|IRCONV_TRUNC);
243 goto xstore;
246 244
247 /* Destination is an array. */ 245 /* Destination is an array. */
248 case CCX(A, A): 246 case CCX(A, A):
@@ -269,24 +267,32 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
269 lua_assert(!ctype_isenum(sinfo)); 267 lua_assert(!ctype_isenum(sinfo));
270 if (ctype_isnum(sinfo)) { 268 if (ctype_isnum(sinfo)) {
271 IRType t = crec_ct2irt(s); 269 IRType t = crec_ct2irt(s);
270 TRef tr;
272 if ((sinfo & CTF_BOOL)) 271 if ((sinfo & CTF_BOOL))
273 goto err_nyi; /* NYI: specialize to the result. */ 272 goto err_nyi; /* NYI: specialize to the result. */
274 if (t == IRT_CDATA) 273 if (t == IRT_CDATA)
275 goto err_nyi; /* NYI: copyval of >64 bit integers. */ 274 goto err_nyi; /* NYI: copyval of >64 bit integers. */
276 if (t >= IRT_U32) 275 tr = emitir(IRT(IR_XLOAD, t), sp, 0);
277 goto err_nyi; /* NYI: on-trace handling of U32/I64/U64. */ 276 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */
278 return emitir(IRT(IR_XLOAD, t), sp, 0); 277 tr = emitir(IRT(IR_CONV, IRT_NUM), tr, t);
278 } 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);
280 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp,
281 lj_ir_kintp(J, sizeof(GCcdata)));
282 emitir(IRT(IR_XSTORE, t), ptr, tr);
283 return dp;
284 }
285 return tr;
279 } else if (ctype_isptr(sinfo)) { 286 } else if (ctype_isptr(sinfo)) {
280 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; 287 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32;
281 sp = emitir(IRT(IR_XLOAD, t), sp, 0); 288 sp = emitir(IRT(IR_XLOAD, t), sp, 0);
282 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { 289 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
283 cts->L = J->L; 290 cts->L = J->L;
284 sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */ 291 sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
285 } else if (ctype_iscomplex(sinfo)) { 292 } else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
286 IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_CDATA; 293 IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_FLOAT;
287 ptrdiff_t esz = (ptrdiff_t)(s->size >> 1); 294 ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
288 TRef ptr, tr1, tr2, dp; 295 TRef ptr, tr1, tr2, dp;
289 if (t == IRT_CDATA) goto err_nyi; /* NYI: float IRType. */
290 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); 296 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
291 tr1 = emitir(IRT(IR_XLOAD, t), sp, 0); 297 tr1 = emitir(IRT(IR_XLOAD, t), sp, 0);
292 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz)); 298 ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz));
@@ -301,6 +307,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
301 err_nyi: 307 err_nyi:
302 lj_trace_err(J, LJ_TRERR_NYICONV); 308 lj_trace_err(J, LJ_TRERR_NYICONV);
303 } 309 }
310 /* Box pointer or ref. */
304 return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, sid), sp); 311 return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, sid), sp);
305} 312}
306 313
diff --git a/src/lj_ir.h b/src/lj_ir.h
index 8154949c..75635f93 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -222,6 +222,7 @@ IRFLDEF(FLENUM)
222/* CONV mode, stored in op2. Lowest 8 bits is the IRType of the source. */ 222/* CONV mode, stored in op2. Lowest 8 bits is the IRType of the source. */
223#define IRCONV_TRUNC 0x100 /* Truncate number to integer. */ 223#define IRCONV_TRUNC 0x100 /* Truncate number to integer. */
224#define IRCONV_SEXT 0x200 /* Sign-extend integer to integer. */ 224#define IRCONV_SEXT 0x200 /* Sign-extend integer to integer. */
225#define IRCONV_MODEMASK 0x3ff
225#define IRCONV_CSH 10 226#define IRCONV_CSH 10
226/* Number to integer conversion mode. Ordered by strength of the checks. */ 227/* Number to integer conversion mode. Ordered by strength of the checks. */
227#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */ 228#define IRCONV_TOBIT (0<<IRCONV_CSH) /* None. Cache only: TOBIT conv. */
@@ -348,6 +349,7 @@ IRTDEF(IRTENUM)
348 /* Native pointer type and the corresponding integer type. */ 349 /* Native pointer type and the corresponding integer type. */
349 IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32, 350 IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32,
350 IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT, 351 IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT,
352 IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32,
351 353
352 /* Additional flags. */ 354 /* Additional flags. */
353 IRT_MARK = 0x20, /* Marker for misc. purposes. */ 355 IRT_MARK = 0x20, /* Marker for misc. purposes. */