diff --git a/src/lj_ccall.c b/src/lj_ccall.c index a6b0a8fd..00c1c7cf 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c @@ -585,9 +585,9 @@ #define CCALL_HANDLE_REGARG \ if (isfp) { \ - if (nfpr < maxgpr) { dp = &cc->fpr[nfpr++]; goto done; } \ + if (nfpr < CCALL_NARG_FPR) { dp = &cc->fpr[nfpr++]; goto done; } \ } else { \ - if (ngpr < CCALL_NARG_FPR) { dp = &cc->gpr[ngpr++]; goto done; } \ + if (ngpr < maxgpr) { dp = &cc->gpr[ngpr++]; goto done; } \ } #else @@ -1074,6 +1074,15 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, *(int64_t *)dp = (int64_t)*(int32_t *)dp; /* Sign-extend to 64 bit. */ } #endif +#if LJ_TARGET_S390X + /* Arguments need to be sign-/zero-extended to 64-bits. */ + if ((ctype_isinteger_or_bool(d->info) || ctype_isenum(d->info)) && d->size <= 4) { + if (d->info & CTF_UNSIGNED) + *(uint64_t *)dp = (uint64_t)*(uint32_t *)dp; + else + *(int64_t *)dp = (int64_t)*(int32_t *)dp; + } +#endif #if LJ_TARGET_X64 && LJ_ABI_WIN if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ if (nfpr == ngpr) diff --git a/src/vm_s390x.dasc b/src/vm_s390x.dasc index f8be2847..f0289de6 100644 --- a/src/vm_s390x.dasc +++ b/src/vm_s390x.dasc @@ -2164,21 +2164,22 @@ static void build_subroutines(BuildCtx *ctx) | basr r14, r7 | | stg CRET1, CCSTATE->gpr[0] - | stg f0, CCSTATE->fpr[0] + | std f0, CCSTATE->fpr[0] | | agf sp, CCSTATE->spadj | lmg r6, r15, 48(sp) | br r14 | |2: + | sll r1, 3 | lay r10, (offsetof(CCallState, stack))(CCSTATE) // Source. | lay r11, (CCALL_SPS_EXTRA*8)(sp) // Destination. |3: | chi r1, 256 | jl >4 | mvc 0(256, r11), 0(r10) - | la r10, 256*8(r10) - | la r11, 256*8(r11) + | la r10, 256(r10) + | la r11, 256(r11) | ahi r1, -256 | j <3 |