root/lj_ccall.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2 ** FFI C call handling.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #ifndef _LJ_CCALL_H
   7 #define _LJ_CCALL_H
   8 
   9 #include "lj_obj.h"
  10 #include "lj_ctype.h"
  11 
  12 #if LJ_HASFFI
  13 
  14 /* -- C calling conventions ----------------------------------------------- */
  15 
  16 #if LJ_TARGET_X86ORX64
  17 
  18 #if LJ_TARGET_X86
  19 #define CCALL_NARG_GPR          2       /* For fastcall arguments. */
  20 #define CCALL_NARG_FPR          0
  21 #define CCALL_NRET_GPR          2
  22 #define CCALL_NRET_FPR          1       /* For FP results on x87 stack. */
  23 #define CCALL_ALIGN_STACKARG    0       /* Don't align argument on stack. */
  24 #elif LJ_ABI_WIN
  25 #define CCALL_NARG_GPR          4
  26 #define CCALL_NARG_FPR          4
  27 #define CCALL_NRET_GPR          1
  28 #define CCALL_NRET_FPR          1
  29 #define CCALL_SPS_EXTRA         4
  30 #else
  31 #define CCALL_NARG_GPR          6
  32 #define CCALL_NARG_FPR          8
  33 #define CCALL_NRET_GPR          2
  34 #define CCALL_NRET_FPR          2
  35 #define CCALL_VECTOR_REG        1       /* Pass vectors in registers. */
  36 #endif
  37 
  38 #define CCALL_SPS_FREE          1
  39 #define CCALL_ALIGN_CALLSTATE   16
  40 
  41 typedef LJ_ALIGN(16) union FPRArg {
  42   double d[2];
  43   float f[4];
  44   uint8_t b[16];
  45   uint16_t s[8];
  46   int i[4];
  47   int64_t l[2];
  48 } FPRArg;
  49 
  50 typedef intptr_t GPRArg;
  51 
  52 #elif LJ_TARGET_ARM
  53 
  54 #define CCALL_NARG_GPR          4
  55 #define CCALL_NRET_GPR          2       /* For softfp double. */
  56 #if LJ_ABI_SOFTFP
  57 #define CCALL_NARG_FPR          0
  58 #define CCALL_NRET_FPR          0
  59 #else
  60 #define CCALL_NARG_FPR          8
  61 #define CCALL_NRET_FPR          4
  62 #endif
  63 #define CCALL_SPS_FREE          0
  64 
  65 typedef intptr_t GPRArg;
  66 typedef union FPRArg {
  67   double d;
  68   float f[2];
  69 } FPRArg;
  70 
  71 #elif LJ_TARGET_PPC
  72 
  73 #define CCALL_NARG_GPR          8
  74 #define CCALL_NARG_FPR          8
  75 #define CCALL_NRET_GPR          4       /* For complex double. */
  76 #define CCALL_NRET_FPR          1
  77 #define CCALL_SPS_EXTRA         4
  78 #define CCALL_SPS_FREE          0
  79 
  80 typedef intptr_t GPRArg;
  81 typedef double FPRArg;
  82 
  83 #elif LJ_TARGET_PPCSPE
  84 
  85 #define CCALL_NARG_GPR          8
  86 #define CCALL_NARG_FPR          0
  87 #define CCALL_NRET_GPR          4       /* For softfp complex double. */
  88 #define CCALL_NRET_FPR          0
  89 #define CCALL_SPS_FREE          0       /* NYI */
  90 
  91 typedef intptr_t GPRArg;
  92 
  93 #elif LJ_TARGET_MIPS
  94 
  95 #define CCALL_NARG_GPR          4
  96 #define CCALL_NARG_FPR          2
  97 #define CCALL_NRET_GPR          2
  98 #define CCALL_NRET_FPR          2
  99 #define CCALL_SPS_EXTRA         7
 100 #define CCALL_SPS_FREE          1
 101 
 102 typedef intptr_t GPRArg;
 103 typedef union FPRArg {
 104   double d;
 105   struct { LJ_ENDIAN_LOHI(float f; , float g;) };
 106 } FPRArg;
 107 
 108 #else
 109 #error "Missing calling convention definitions for this architecture"
 110 #endif
 111 
 112 #ifndef CCALL_SPS_EXTRA
 113 #define CCALL_SPS_EXTRA         0
 114 #endif
 115 #ifndef CCALL_VECTOR_REG
 116 #define CCALL_VECTOR_REG        0
 117 #endif
 118 #ifndef CCALL_ALIGN_STACKARG
 119 #define CCALL_ALIGN_STACKARG    1
 120 #endif
 121 #ifndef CCALL_ALIGN_CALLSTATE
 122 #define CCALL_ALIGN_CALLSTATE   8
 123 #endif
 124 
 125 #define CCALL_NUM_GPR \
 126   (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
 127 #define CCALL_NUM_FPR \
 128   (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
 129 
 130 /* Check against constants in lj_ctype.h. */
 131 LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
 132 LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
 133 
 134 #define CCALL_MAXSTACK          32
 135 
 136 /* -- C call state -------------------------------------------------------- */
 137 
 138 typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
 139   void (*func)(void);           /* Pointer to called function. */
 140   uint32_t spadj;               /* Stack pointer adjustment. */
 141   uint8_t nsp;                  /* Number of stack slots. */
 142   uint8_t retref;               /* Return value by reference. */
 143 #if LJ_TARGET_X64
 144   uint8_t ngpr;                 /* Number of arguments in GPRs. */
 145   uint8_t nfpr;                 /* Number of arguments in FPRs. */
 146 #elif LJ_TARGET_X86
 147   uint8_t resx87;               /* Result on x87 stack: 1:float, 2:double. */
 148 #elif LJ_TARGET_PPC
 149   uint8_t nfpr;                 /* Number of arguments in FPRs. */
 150 #endif
 151 #if LJ_32
 152   int32_t align1;
 153 #endif
 154 #if CCALL_NUM_FPR
 155   FPRArg fpr[CCALL_NUM_FPR];    /* Arguments/results in FPRs. */
 156 #endif
 157   GPRArg gpr[CCALL_NUM_GPR];    /* Arguments/results in GPRs. */
 158   GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
 159 } CCallState;
 160 
 161 /* -- C call handling ----------------------------------------------------- */
 162 
 163 /* Really belongs to lj_vm.h. */
 164 LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
 165 
 166 LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
 167 LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
 168 
 169 #endif
 170 
 171 #endif

/* [<][>][^][v][top][bottom][index][help] */