/* Find out how (by value/ref) and where (GPR/FPR) to pass an argument. */
if (ctype_isnum(d->info)) {
if (sz > 8) goto err_nyi;
- if ((d->info & CTF_FP)) {
+ if ((d->info & CTF_FP))
isfp = 1;
- } else if (sz < CTSIZE_PTR) {
- d = ctype_get(cts, CTID_INT_PSZ);
- }
} else if (ctype_isvector(d->info)) {
if (CCALL_VECTOR_REG && (sz == 8 || sz == 16))
isfp = 1;
dp = rp;
}
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
+ /* Extend passed integers to 32 bits at least. */
+ if (ctype_isinteger_or_bool(d->info) && d->size < 4) {
+ if (d->info & CTF_UNSIGNED)
+ *(uint32_t *)dp = d->size == 1 ? (uint32_t)*(uint8_t *)dp :
+ (uint32_t)*(uint16_t *)dp;
+ else
+ *(int32_t *)dp = d->size == 1 ? (int32_t)*(int8_t *)dp :
+ (int32_t)*(int16_t *)dp;
+ }
#if LJ_TARGET_X64 && LJ_ABI_WIN
if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
if (nfpr == ngpr)
CCallState *cc, int *ret)
{
CType *ctr = ctype_rawchild(cts, ct);
- void *sp = &cc->gpr[0];
+ uint8_t *sp = (uint8_t *)&cc->gpr[0];
if (ctype_isvoid(ctr->info)) {
*ret = 0; /* Zero results. */
return 0; /* No additional GC step. */
CCALL_HANDLE_COMPLEXRET2
return 1; /* One GC step. */
}
+ if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR)
+ sp += (CTSIZE_PTR - ctr->size);
#ifdef CCALL_HANDLE_RET
CCALL_HANDLE_RET
#endif
#if CCALL_NUM_FPR
if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
- sp = &cc->fpr[0];
+ sp = (uint8_t *)&cc->fpr[0];
#endif
/* No reference types end up here, so there's no need for the CTypeID. */
lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr);
- return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, (uint8_t *)sp);
+ return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp);
}
/* Call C function. */
if (!(ctype_isnum(d->info) || ctype_isptr(d->info) ||
ctype_isenum(d->info)))
lj_trace_err(J, LJ_TRERR_NYICALL);
- args[n] = crec_ct_tv(J, d, 0, J->base[n+1], &rd->argv[n+1]);
+ tr = crec_ct_tv(J, d, 0, J->base[n+1], &rd->argv[n+1]);
+ if (ctype_isinteger_or_bool(d->info) && d->size < 4) {
+ if ((d->info & CTF_UNSIGNED))
+ tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_U8 : IRT_U16, 0);
+ else
+ tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16, IRCONV_SEXT);
+ }
+ args[n] = tr;
}
tr = args[0];
for (i = 1; i < n; i++)
tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
if (t == IRT_FLOAT || t == IRT_U32) {
tr = emitconv(tr, IRT_NUM, t, 0);
+ } else if (t == IRT_I8 || t == IRT_I16) {
+ tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
+ } else if (t == IRT_U8 || t == IRT_U16) {
+ tr = emitconv(tr, IRT_INT, t, 0);
} else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
(t == IRT_I64 || t == IRT_U64)) {
TRef trid = lj_ir_kint(J, ctype_cid(ct->info));