Skip to content

Commit

Permalink
PPC: Add soft-float support to interpreter.
Browse files Browse the repository at this point in the history
Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
Sponsored by Cisco Systems, Inc.
  • Loading branch information
Mike Pall committed Jul 26, 2017
1 parent 7e662e4 commit fd37da0
Show file tree
Hide file tree
Showing 8 changed files with 1,101 additions and 255 deletions.
2 changes: 1 addition & 1 deletion src/host/buildvm_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void emit_asm(BuildCtx *ctx)
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
#endif
#if LJ_TARGET_PPC && !LJ_TARGET_PS3
#if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP
/* Hard-float ABI. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
#endif
Expand Down
29 changes: 24 additions & 5 deletions src/lj_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,29 @@
#else
#define LJ_ARCH_BITS 32
#define LJ_ARCH_NAME "ppc"

#if !defined(LJ_ARCH_HASFPU)
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
#define LJ_ARCH_HASFPU 0
#else
#define LJ_ARCH_HASFPU 1
#endif
#endif

#if !defined(LJ_ABI_SOFTFP)
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
#define LJ_ABI_SOFTFP 1
#else
#define LJ_ABI_SOFTFP 0
#endif
#endif
#endif

#if LJ_ABI_SOFTFP
#define LJ_ARCH_NOJIT 1 /* NYI */
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
#else
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
#endif

#define LJ_TARGET_PPC 1
Expand All @@ -262,7 +285,6 @@
#define LJ_TARGET_MASKSHIFT 0
#define LJ_TARGET_MASKROT 1
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE

#if LJ_TARGET_CONSOLE
#define LJ_ARCH_PPC32ON64 1
Expand Down Expand Up @@ -415,16 +437,13 @@
#error "No support for ILP32 model on ARM64"
#endif
#elif LJ_TARGET_PPC
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
#error "No support for PowerPC CPUs without double-precision FPU"
#endif
#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE
#error "No support for little-endian PPC32"
#endif
#if LJ_ARCH_PPC64
#error "No support for PowerPC 64 bit mode (yet)"
#endif
#ifdef __NO_FPRS__
#if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT)
#error "No support for PPC/e500 anymore (use LuaJIT 2.0)"
#endif
#elif LJ_TARGET_MIPS32
Expand Down
38 changes: 24 additions & 14 deletions src/lj_ccall.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,24 @@
#define CCALL_HANDLE_COMPLEXARG \
/* Pass complex by value in 2 or 4 GPRs. */

#define CCALL_HANDLE_GPR \
/* Try to pass argument in GPRs. */ \
if (n > 1) { \
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
if (ctype_isinteger(d->info) || ctype_isfp(d->info)) \
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
else if (ngpr + n > maxgpr) \
ngpr = maxgpr; /* Prevent reordering. */ \
} \
if (ngpr + n <= maxgpr) { \
dp = &cc->gpr[ngpr]; \
ngpr += n; \
goto done; \
} \

#if LJ_ABI_SOFTFP
#define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR
#else
#define CCALL_HANDLE_REGARG \
if (isfp) { /* Try to pass argument in FPRs. */ \
if (nfpr + 1 <= CCALL_NARG_FPR) { \
Expand All @@ -395,24 +413,16 @@
d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
goto done; \
} \
} else { /* Try to pass argument in GPRs. */ \
if (n > 1) { \
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
if (ctype_isinteger(d->info)) \
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
else if (ngpr + n > maxgpr) \
ngpr = maxgpr; /* Prevent reordering. */ \
} \
if (ngpr + n <= maxgpr) { \
dp = &cc->gpr[ngpr]; \
ngpr += n; \
goto done; \
} \
} else { \
CCALL_HANDLE_GPR \
}
#endif

#if !LJ_ABI_SOFTFP
#define CCALL_HANDLE_RET \
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
#endif

#elif LJ_TARGET_MIPS32
/* -- MIPS o32 calling conventions ---------------------------------------- */
Expand Down Expand Up @@ -1080,7 +1090,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
}
if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */

#if LJ_TARGET_X64 || LJ_TARGET_PPC
#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
cc->nfpr = nfpr; /* Required for vararg functions. */
#endif
cc->nsp = nsp;
Expand Down
4 changes: 2 additions & 2 deletions src/lj_ccall.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ typedef union FPRArg {
#elif LJ_TARGET_PPC

#define CCALL_NARG_GPR 8
#define CCALL_NARG_FPR 8
#define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 8)
#define CCALL_NRET_GPR 4 /* For complex double. */
#define CCALL_NRET_FPR 1
#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 1)
#define CCALL_SPS_EXTRA 4
#define CCALL_SPS_FREE 0

Expand Down
30 changes: 21 additions & 9 deletions src/lj_ccallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,23 @@ void lj_ccallback_mcode_free(CTState *cts)

#elif LJ_TARGET_PPC

#define CALLBACK_HANDLE_GPR \
if (n > 1) { \
lua_assert(((LJ_ABI_SOFTFP && ctype_isnum(cta->info)) || /* double. */ \
ctype_isinteger(cta->info)) && n == 2); /* int64_t. */ \
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
} \
if (ngpr + n <= maxgpr) { \
sp = &cts->cb.gpr[ngpr]; \
ngpr += n; \
goto done; \
}

#if LJ_ABI_SOFTFP
#define CALLBACK_HANDLE_REGARG \
CALLBACK_HANDLE_GPR \
UNUSED(isfp);
#else
#define CALLBACK_HANDLE_REGARG \
if (isfp) { \
if (nfpr + 1 <= CCALL_NARG_FPR) { \
Expand All @@ -427,20 +444,15 @@ void lj_ccallback_mcode_free(CTState *cts)
goto done; \
} \
} else { /* Try to pass argument in GPRs. */ \
if (n > 1) { \
lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
} \
if (ngpr + n <= maxgpr) { \
sp = &cts->cb.gpr[ngpr]; \
ngpr += n; \
goto done; \
} \
CALLBACK_HANDLE_GPR \
}
#endif

#if !LJ_ABI_SOFTFP
#define CALLBACK_HANDLE_RET \
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
*(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
#endif

#elif LJ_TARGET_MIPS32

Expand Down
2 changes: 1 addition & 1 deletion src/lj_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */
#define CFRAME_OFS_L 36
#define CFRAME_OFS_PC 32
#define CFRAME_OFS_MULTRES 28
#define CFRAME_SIZE 272
#define CFRAME_SIZE (LJ_ARCH_HASFPU ? 272 : 128)
#define CFRAME_SHIFT_MULTRES 3
#endif
#elif LJ_TARGET_MIPS32
Expand Down
2 changes: 1 addition & 1 deletion src/lj_ircall.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1];
#define fp64_f2l __aeabi_f2lz
#define fp64_f2ul __aeabi_f2ulz
#endif
#elif LJ_TARGET_MIPS
#elif LJ_TARGET_MIPS || LJ_TARGET_PPC
#define softfp_add __adddf3
#define softfp_sub __subdf3
#define softfp_mul __muldf3
Expand Down
Loading

0 comments on commit fd37da0

Please sign in to comment.