PPC: Add machine-specific part of FFI.
This commit is contained in:
parent
26106759d4
commit
4008b351f4
@ -2382,7 +2382,62 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|
|
|
|
||||||
|->vm_ffi_call:
|
|->vm_ffi_call:
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
| NYI
|
| .type CCSTATE, CCallState, CARG1
|
||||||
|
| lwz TMP1, CCSTATE->spadj
|
||||||
|
| mflr TMP0
|
||||||
|
| lbz CARG2, CCSTATE->nsp
|
||||||
|
| lbz CARG3, CCSTATE->nfpr
|
||||||
|
| neg TMP1, TMP1
|
||||||
|
| stw TMP0, 4(sp)
|
||||||
|
| cmpwi cr1, CARG3, 0
|
||||||
|
| mr TMP2, sp
|
||||||
|
| addic. CARG2, CARG2, -1
|
||||||
|
| stwux sp, sp, TMP1
|
||||||
|
| crnot 4*cr1+eq, 4*cr1+eq // For vararg calls.
|
||||||
|
| stw CCSTATE, -4(TMP2)
|
||||||
|
| li TMP3, 0
|
||||||
|
| la TMP1, CCSTATE->stack
|
||||||
|
| slwi CARG2, CARG2, 2
|
||||||
|
| blt >2
|
||||||
|
| la TMP2, 8(sp)
|
||||||
|
|1:
|
||||||
|
| lwzx TMP0, TMP1, CARG2
|
||||||
|
| stwx TMP0, TMP2, CARG2
|
||||||
|
| addic. CARG2, CARG2, -4
|
||||||
|
| bge <1
|
||||||
|
|2:
|
||||||
|
| bne cr1, >3
|
||||||
|
| lfd f1, CCSTATE->fpr[0]
|
||||||
|
| lfd f2, CCSTATE->fpr[1]
|
||||||
|
| lfd f3, CCSTATE->fpr[2]
|
||||||
|
| lfd f4, CCSTATE->fpr[3]
|
||||||
|
| lfd f5, CCSTATE->fpr[4]
|
||||||
|
| lfd f6, CCSTATE->fpr[5]
|
||||||
|
| lfd f7, CCSTATE->fpr[6]
|
||||||
|
| lfd f8, CCSTATE->fpr[7]
|
||||||
|
|3:
|
||||||
|
| lwz TMP0, CCSTATE->func
|
||||||
|
| lwz CARG2, CCSTATE->gpr[1]
|
||||||
|
| lwz CARG3, CCSTATE->gpr[2]
|
||||||
|
| lwz CARG4, CCSTATE->gpr[3]
|
||||||
|
| lwz CARG5, CCSTATE->gpr[4]
|
||||||
|
| mtctr TMP0
|
||||||
|
| lwz r8, CCSTATE->gpr[5]
|
||||||
|
| lwz r9, CCSTATE->gpr[6]
|
||||||
|
| lwz r10, CCSTATE->gpr[7]
|
||||||
|
| lwz CARG1, CCSTATE->gpr[0] // Do this last, since CCSTATE is CARG1.
|
||||||
|
| bctrl
|
||||||
|
| lwz TMP2, 0(sp)
|
||||||
|
| lwz CCSTATE:TMP1, -4(TMP2)
|
||||||
|
| lwz TMP0, 4(TMP2)
|
||||||
|
| stw CARG1, CCSTATE:TMP1->gpr[0]
|
||||||
|
| stfd FARG1, CCSTATE:TMP1->fpr[0]
|
||||||
|
| stw CARG2, CCSTATE:TMP1->gpr[1]
|
||||||
|
| mtlr TMP0
|
||||||
|
| stw CARG3, CCSTATE:TMP1->gpr[2]
|
||||||
|
| mr sp, TMP2
|
||||||
|
| stw CARG4, CCSTATE:TMP1->gpr[3]
|
||||||
|
| blr
|
||||||
#endif
|
#endif
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
@ -2440,7 +2495,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| tonum_i f1, CARG3
|
| tonum_i f1, CARG3
|
||||||
| b >5
|
| b >5
|
||||||
|
|
|
|
||||||
|8: // RA is an integer, RD is a number.
|
|8: // RA is an integer, RD is not an integer.
|
||||||
|
| bgt cr1, ->vmeta_comp
|
||||||
|
| // RA is an integer, RD is a number.
|
||||||
| tonum_i f0, CARG2
|
| tonum_i f0, CARG2
|
||||||
|4:
|
|4:
|
||||||
| lfd f1, 0(RD)
|
| lfd f1, 0(RD)
|
||||||
@ -2498,9 +2555,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lwz CARG2, 4(RA)
|
| lwz CARG2, 4(RA)
|
||||||
| lwzux TMP1, RD, BASE
|
| lwzux TMP1, RD, BASE
|
||||||
| checknum cr0, TMP0
|
| checknum cr0, TMP0
|
||||||
| lwz INS, -4(PC)
|
| lwz TMP2, -4(PC)
|
||||||
| checknum cr1, TMP1
|
| checknum cr1, TMP1
|
||||||
| decode_RD4 TMP2, INS
|
| decode_RD4 TMP2, TMP2
|
||||||
| lwz CARG3, 4(RD)
|
| lwz CARG3, 4(RD)
|
||||||
| cror 4*cr7+gt, 4*cr0+gt, 4*cr1+gt
|
| cror 4*cr7+gt, 4*cr0+gt, 4*cr1+gt
|
||||||
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
||||||
@ -2538,10 +2595,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lwz CARG2, 4(RA)
|
| lwz CARG2, 4(RA)
|
||||||
| lwz CARG3, 4(RD)
|
| lwz CARG3, 4(RD)
|
||||||
}
|
}
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| cmpwi cr7, TMP0, LJ_TCDATA
|
||||||
|
| cmpwi cr5, TMP1, LJ_TCDATA
|
||||||
|
}
|
||||||
| not TMP3, TMP0
|
| not TMP3, TMP0
|
||||||
| cmplw TMP0, TMP1
|
| cmplw TMP0, TMP1
|
||||||
| cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
|
| cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| cror 4*cr7+eq, 4*cr7+eq, 4*cr5+eq
|
||||||
|
}
|
||||||
| cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata?
|
| cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata?
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| beq cr7, ->vmeta_equal_cd
|
||||||
|
}
|
||||||
| cmplw cr5, CARG2, CARG3
|
| cmplw cr5, CARG2, CARG3
|
||||||
| crandc 4*cr0+gt, 4*cr0+eq, 4*cr1+gt // 2: Same type and primitive.
|
| crandc 4*cr0+gt, 4*cr0+eq, 4*cr1+gt // 2: Same type and primitive.
|
||||||
| crorc 4*cr0+lt, 4*cr5+eq, 4*cr0+eq // 1: Same tv or different type.
|
| crorc 4*cr0+lt, 4*cr5+eq, 4*cr0+eq // 1: Same tv or different type.
|
||||||
@ -2587,14 +2654,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lwzux TMP0, RA, BASE
|
| lwzux TMP0, RA, BASE
|
||||||
| srwi RD, RD, 1
|
| srwi RD, RD, 1
|
||||||
| lwz STR:TMP3, 4(RA)
|
| lwz STR:TMP3, 4(RA)
|
||||||
| lwz INS, 0(PC)
|
| lwz TMP2, 0(PC)
|
||||||
| subfic RD, RD, -4
|
| subfic RD, RD, -4
|
||||||
| addi PC, PC, 4
|
| addi PC, PC, 4
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| cmpwi TMP0, LJ_TCDATA
|
||||||
|
}
|
||||||
| lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
|
| lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
|
||||||
| subfic TMP0, TMP0, LJ_TSTR
|
| subfic TMP0, TMP0, LJ_TSTR
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| beq ->vmeta_equal_cd
|
||||||
|
}
|
||||||
| sub TMP1, STR:TMP1, STR:TMP3
|
| sub TMP1, STR:TMP1, STR:TMP3
|
||||||
| or TMP0, TMP0, TMP1
|
| or TMP0, TMP0, TMP1
|
||||||
| decode_RD4 TMP2, INS
|
| decode_RD4 TMP2, TMP2
|
||||||
| subfic TMP0, TMP0, 0
|
| subfic TMP0, TMP0, 0
|
||||||
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
||||||
| subfe TMP1, TMP1, TMP1
|
| subfe TMP1, TMP1, TMP1
|
||||||
@ -2616,9 +2689,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lwz CARG2, 4(RA)
|
| lwz CARG2, 4(RA)
|
||||||
| lwzux TMP1, RD, KBASE
|
| lwzux TMP1, RD, KBASE
|
||||||
| checknum cr0, TMP0
|
| checknum cr0, TMP0
|
||||||
| lwz INS, -4(PC)
|
| lwz TMP2, -4(PC)
|
||||||
| checknum cr1, TMP1
|
| checknum cr1, TMP1
|
||||||
| decode_RD4 TMP2, INS
|
| decode_RD4 TMP2, TMP2
|
||||||
| lwz CARG3, 4(RD)
|
| lwz CARG3, 4(RD)
|
||||||
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
||||||
if (vk) {
|
if (vk) {
|
||||||
@ -2639,9 +2712,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lwzx TMP0, BASE, RA
|
| lwzx TMP0, BASE, RA
|
||||||
| addi PC, PC, 4
|
| addi PC, PC, 4
|
||||||
| lfdx f0, BASE, RA
|
| lfdx f0, BASE, RA
|
||||||
| lwz INS, -4(PC)
|
| lwz TMP2, -4(PC)
|
||||||
| lfdx f1, KBASE, RD
|
| lfdx f1, KBASE, RD
|
||||||
| decode_RD4 TMP2, INS
|
| decode_RD4 TMP2, TMP2
|
||||||
| checknum TMP0
|
| checknum TMP0
|
||||||
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
||||||
| bge >3
|
| bge >3
|
||||||
@ -2695,11 +2768,17 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
|
| // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
|
||||||
| lwzx TMP0, BASE, RA
|
| lwzx TMP0, BASE, RA
|
||||||
| srwi TMP1, RD, 3
|
| srwi TMP1, RD, 3
|
||||||
| lwz INS, 0(PC)
|
| lwz TMP2, 0(PC)
|
||||||
| not TMP1, TMP1
|
| not TMP1, TMP1
|
||||||
| addi PC, PC, 4
|
| addi PC, PC, 4
|
||||||
|
if (LJ_HASFFI) {
|
||||||
|
| cmpwi TMP0, LJ_TCDATA
|
||||||
|
}
|
||||||
| sub TMP0, TMP0, TMP1
|
| sub TMP0, TMP0, TMP1
|
||||||
| decode_RD4 TMP2, INS
|
if (LJ_HASFFI) {
|
||||||
|
| beq ->vmeta_equal_cd
|
||||||
|
}
|
||||||
|
| decode_RD4 TMP2, TMP2
|
||||||
| addic TMP0, TMP0, -1
|
| addic TMP0, TMP0, -1
|
||||||
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
| addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
|
||||||
| subfe TMP1, TMP1, TMP1
|
| subfe TMP1, TMP1, TMP1
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -163,7 +163,6 @@
|
|||||||
#define LJ_TARGET_MASKROT 1
|
#define LJ_TARGET_MASKROT 1
|
||||||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||||
#define LJ_ARCH_NOFFI 1 /* NYI: comparisons, calls. */
|
|
||||||
#define LJ_ARCH_NOJIT 1
|
#define LJ_ARCH_NOJIT 1
|
||||||
|
|
||||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_PPCSPE
|
#elif LUAJIT_TARGET == LUAJIT_ARCH_PPCSPE
|
||||||
|
@ -205,6 +205,54 @@
|
|||||||
goto done; \
|
goto done; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif LJ_TARGET_PPC
|
||||||
|
/* -- PPC calling conventions --------------------------------------------- */
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_STRUCTRET \
|
||||||
|
cc->retref = 1; /* Return all structs by reference. */ \
|
||||||
|
cc->gpr[ngpr++] = (GPRArg)dp;
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_COMPLEXRET \
|
||||||
|
/* Complex values are returned in 2 or 4 GPRs. */ \
|
||||||
|
cc->retref = 0;
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_COMPLEXRET2 \
|
||||||
|
memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_STRUCTARG \
|
||||||
|
rp = cdataptr(lj_cdata_new(cts, did, sz)); \
|
||||||
|
sz = CTSIZE_PTR; /* Pass all structs by reference. */
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_COMPLEXARG \
|
||||||
|
/* Pass complex by value in 2 or 4 GPRs. */
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_REGARG \
|
||||||
|
if (isfp) { /* Try to pass argument in FPRs. */ \
|
||||||
|
if (nfpr + 1 <= CCALL_NARG_FPR) { \
|
||||||
|
dp = &cc->fpr[nfpr]; \
|
||||||
|
nfpr += 1; \
|
||||||
|
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; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_RET \
|
||||||
|
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||||
|
ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
|
||||||
|
|
||||||
#elif LJ_TARGET_PPCSPE
|
#elif LJ_TARGET_PPCSPE
|
||||||
/* -- PPC/SPE calling conventions ----------------------------------------- */
|
/* -- PPC/SPE calling conventions ----------------------------------------- */
|
||||||
|
|
||||||
@ -530,7 +578,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 (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
|
||||||
|
|
||||||
#if LJ_TARGET_X64
|
#if LJ_TARGET_X64 || LJ_TARGET_PPC || LJ_TARGET_PPCSPE
|
||||||
cc->nfpr = nfpr; /* Required for vararg functions. */
|
cc->nfpr = nfpr; /* Required for vararg functions. */
|
||||||
#endif
|
#endif
|
||||||
cc->nsp = nsp;
|
cc->nsp = nsp;
|
||||||
@ -565,6 +613,9 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
|
|||||||
CCALL_HANDLE_COMPLEXRET2
|
CCALL_HANDLE_COMPLEXRET2
|
||||||
return 1; /* One GC step. */
|
return 1; /* One GC step. */
|
||||||
}
|
}
|
||||||
|
#ifdef CCALL_HANDLE_RET
|
||||||
|
CCALL_HANDLE_RET
|
||||||
|
#endif
|
||||||
#if CCALL_NUM_FPR
|
#if CCALL_NUM_FPR
|
||||||
if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
|
if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
|
||||||
sp = &cc->fpr[0];
|
sp = &cc->fpr[0];
|
||||||
|
@ -53,10 +53,22 @@ typedef intptr_t GPRArg;
|
|||||||
#define CCALL_NARG_FPR 0
|
#define CCALL_NARG_FPR 0
|
||||||
#define CCALL_NRET_GPR 2 /* For softfp double. */
|
#define CCALL_NRET_GPR 2 /* For softfp double. */
|
||||||
#define CCALL_NRET_FPR 0
|
#define CCALL_NRET_FPR 0
|
||||||
#define CCALL_SPS_FREE 0 /* NYI */
|
#define CCALL_SPS_FREE 0
|
||||||
|
|
||||||
typedef intptr_t GPRArg;
|
typedef intptr_t GPRArg;
|
||||||
|
|
||||||
|
#elif LJ_TARGET_PPC
|
||||||
|
|
||||||
|
#define CCALL_NARG_GPR 8
|
||||||
|
#define CCALL_NARG_FPR 8
|
||||||
|
#define CCALL_NRET_GPR 4 /* For complex double. */
|
||||||
|
#define CCALL_NRET_FPR 1
|
||||||
|
#define CCALL_SPS_EXTRA 3
|
||||||
|
#define CCALL_SPS_FREE 1
|
||||||
|
|
||||||
|
typedef intptr_t GPRArg;
|
||||||
|
typedef double FPRArg;
|
||||||
|
|
||||||
#elif LJ_TARGET_PPCSPE
|
#elif LJ_TARGET_PPCSPE
|
||||||
|
|
||||||
#define CCALL_NARG_GPR 8
|
#define CCALL_NARG_GPR 8
|
||||||
@ -100,8 +112,13 @@ typedef struct CCallState {
|
|||||||
uint8_t nfpr; /* Number of arguments in FPRs. */
|
uint8_t nfpr; /* Number of arguments in FPRs. */
|
||||||
#elif LJ_TARGET_X86
|
#elif LJ_TARGET_X86
|
||||||
uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
|
uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
|
||||||
|
#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
|
||||||
|
uint8_t nfpr; /* Number of arguments in FPRs. */
|
||||||
#endif
|
#endif
|
||||||
#if CCALL_NUM_FPR
|
#if CCALL_NUM_FPR
|
||||||
|
#if LJ_32
|
||||||
|
int32_t align1;
|
||||||
|
#endif
|
||||||
FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
|
FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
|
||||||
#endif
|
#endif
|
||||||
GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
|
GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
|
||||||
|
Loading…
Reference in New Issue
Block a user