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_ARM64
  72 
  73 #define CCALL_NARG_GPR          8
  74 #define CCALL_NRET_GPR          2
  75 #define CCALL_NARG_FPR          8
  76 #define CCALL_NRET_FPR          4
  77 #define CCALL_SPS_FREE          0
  78 
  79 typedef intptr_t GPRArg;
  80 typedef union FPRArg {
  81   double d;
  82   struct { LJ_ENDIAN_LOHI(float f; , float g;) };
  83   struct { LJ_ENDIAN_LOHI(uint32_t lo; , uint32_t hi;) };
  84 } FPRArg;
  85 
  86 #elif LJ_TARGET_PPC
  87 
  88 #define CCALL_NARG_GPR          8
  89 #define CCALL_NARG_FPR          (LJ_ABI_SOFTFP ? 0 : 8)
  90 #define CCALL_NRET_GPR          4       /* For complex double. */
  91 #define CCALL_NRET_FPR          (LJ_ABI_SOFTFP ? 0 : 1)
  92 #define CCALL_SPS_EXTRA         4
  93 #define CCALL_SPS_FREE          0
  94 
  95 typedef intptr_t GPRArg;
  96 typedef double FPRArg;
  97 
  98 #elif LJ_TARGET_MIPS32
  99 
 100 #define CCALL_NARG_GPR          4
 101 #define CCALL_NARG_FPR          (LJ_ABI_SOFTFP ? 0 : 2)
 102 #define CCALL_NRET_GPR          (LJ_ABI_SOFTFP ? 4 : 2)
 103 #define CCALL_NRET_FPR          (LJ_ABI_SOFTFP ? 0 : 2)
 104 #define CCALL_SPS_EXTRA         7
 105 #define CCALL_SPS_FREE          1
 106 
 107 typedef intptr_t GPRArg;
 108 typedef union FPRArg {
 109   double d;
 110   struct { LJ_ENDIAN_LOHI(float f; , float g;) };
 111 } FPRArg;
 112 
 113 #elif LJ_TARGET_MIPS64
 114 
 115 /* FP args are positional and overlay the GPR array. */
 116 #define CCALL_NARG_GPR          8
 117 #define CCALL_NARG_FPR          0
 118 #define CCALL_NRET_GPR          2
 119 #define CCALL_NRET_FPR          (LJ_ABI_SOFTFP ? 0 : 2)
 120 #define CCALL_SPS_EXTRA         3
 121 #define CCALL_SPS_FREE          1
 122 
 123 typedef intptr_t GPRArg;
 124 typedef union FPRArg {
 125   double d;
 126   struct { LJ_ENDIAN_LOHI(float f; , float g;) };
 127 } FPRArg;
 128 
 129 #else
 130 #error "Missing calling convention definitions for this architecture"
 131 #endif
 132 
 133 #ifndef CCALL_SPS_EXTRA
 134 #define CCALL_SPS_EXTRA         0
 135 #endif
 136 #ifndef CCALL_VECTOR_REG
 137 #define CCALL_VECTOR_REG        0
 138 #endif
 139 #ifndef CCALL_ALIGN_STACKARG
 140 #define CCALL_ALIGN_STACKARG    1
 141 #endif
 142 #ifndef CCALL_ALIGN_CALLSTATE
 143 #define CCALL_ALIGN_CALLSTATE   8
 144 #endif
 145 
 146 #define CCALL_NUM_GPR \
 147   (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
 148 #define CCALL_NUM_FPR \
 149   (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
 150 
 151 /* Check against constants in lj_ctype.h. */
 152 LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
 153 LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
 154 
 155 #define CCALL_MAXSTACK          32
 156 
 157 /* -- C call state -------------------------------------------------------- */
 158 
 159 typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
 160   void (*func)(void);           /* Pointer to called function. */
 161   uint32_t spadj;               /* Stack pointer adjustment. */
 162   uint8_t nsp;                  /* Number of stack slots. */
 163   uint8_t retref;               /* Return value by reference. */
 164 #if LJ_TARGET_X64
 165   uint8_t ngpr;                 /* Number of arguments in GPRs. */
 166   uint8_t nfpr;                 /* Number of arguments in FPRs. */
 167 #elif LJ_TARGET_X86
 168   uint8_t resx87;               /* Result on x87 stack: 1:float, 2:double. */
 169 #elif LJ_TARGET_ARM64
 170   void *retp;                   /* Aggregate return pointer in x8. */
 171 #elif LJ_TARGET_PPC
 172   uint8_t nfpr;                 /* Number of arguments in FPRs. */
 173 #endif
 174 #if LJ_32
 175   int32_t align1;
 176 #endif
 177 #if CCALL_NUM_FPR
 178   FPRArg fpr[CCALL_NUM_FPR];    /* Arguments/results in FPRs. */
 179 #endif
 180   GPRArg gpr[CCALL_NUM_GPR];    /* Arguments/results in GPRs. */
 181   GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
 182 } CCallState;
 183 
 184 /* -- C call handling ----------------------------------------------------- */
 185 
 186 /* Really belongs to lj_vm.h. */
 187 LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
 188 
 189 LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
 190 LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
 191 
 192 #endif
 193 
 194 #endif

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