src/lj_ccall.h - luajit-2.0-src

Global variables defined

Data types defined

Macros defined

Source code

  1. /*
  2. ** FFI C call handling.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. */

  5. #ifndef _LJ_CCALL_H
  6. #define _LJ_CCALL_H

  7. #include "lj_obj.h"
  8. #include "lj_ctype.h"

  9. #if LJ_HASFFI

  10. /* -- C calling conventions ----------------------------------------------- */

  11. #if LJ_TARGET_X86ORX64

  12. #if LJ_TARGET_X86
  13. #define CCALL_NARG_GPR                2        /* For fastcall arguments. */
  14. #define CCALL_NARG_FPR                0
  15. #define CCALL_NRET_GPR                2
  16. #define CCALL_NRET_FPR                1        /* For FP results on x87 stack. */
  17. #define CCALL_ALIGN_STACKARG        0        /* Don't align argument on stack. */
  18. #elif LJ_ABI_WIN
  19. #define CCALL_NARG_GPR                4
  20. #define CCALL_NARG_FPR                4
  21. #define CCALL_NRET_GPR                1
  22. #define CCALL_NRET_FPR                1
  23. #define CCALL_SPS_EXTRA                4
  24. #else
  25. #define CCALL_NARG_GPR                6
  26. #define CCALL_NARG_FPR                8
  27. #define CCALL_NRET_GPR                2
  28. #define CCALL_NRET_FPR                2
  29. #define CCALL_VECTOR_REG        1        /* Pass vectors in registers. */
  30. #endif

  31. #define CCALL_SPS_FREE                1
  32. #define CCALL_ALIGN_CALLSTATE        16

  33. typedef LJ_ALIGN(16) union FPRArg {
  34.   double d[2];
  35.   float f[4];
  36.   uint8_t b[16];
  37.   uint16_t s[8];
  38.   int i[4];
  39.   int64_t l[2];
  40. } FPRArg;

  41. typedef intptr_t GPRArg;

  42. #elif LJ_TARGET_ARM

  43. #define CCALL_NARG_GPR                4
  44. #define CCALL_NRET_GPR                2        /* For softfp double. */
  45. #if LJ_ABI_SOFTFP
  46. #define CCALL_NARG_FPR                0
  47. #define CCALL_NRET_FPR                0
  48. #else
  49. #define CCALL_NARG_FPR                8
  50. #define CCALL_NRET_FPR                4
  51. #endif
  52. #define CCALL_SPS_FREE                0

  53. typedef intptr_t GPRArg;
  54. typedef union FPRArg {
  55.   double d;
  56.   float f[2];
  57. } FPRArg;

  58. #elif LJ_TARGET_ARM64

  59. #define CCALL_NARG_GPR                8
  60. #define CCALL_NRET_GPR                2
  61. #define CCALL_NARG_FPR                8
  62. #define CCALL_NRET_FPR                4
  63. #define CCALL_SPS_FREE                0

  64. typedef intptr_t GPRArg;
  65. typedef union FPRArg {
  66.   double d;
  67.   float f;
  68.   uint32_t u32;
  69. } FPRArg;

  70. #elif LJ_TARGET_PPC

  71. #define CCALL_NARG_GPR                8
  72. #define CCALL_NARG_FPR                8
  73. #define CCALL_NRET_GPR                4        /* For complex double. */
  74. #define CCALL_NRET_FPR                1
  75. #define CCALL_SPS_EXTRA                4
  76. #define CCALL_SPS_FREE                0

  77. typedef intptr_t GPRArg;
  78. typedef double FPRArg;

  79. #elif LJ_TARGET_MIPS

  80. #define CCALL_NARG_GPR                4
  81. #define CCALL_NARG_FPR                2
  82. #define CCALL_NRET_GPR                2
  83. #define CCALL_NRET_FPR                2
  84. #define CCALL_SPS_EXTRA                7
  85. #define CCALL_SPS_FREE                1

  86. typedef intptr_t GPRArg;
  87. typedef union FPRArg {
  88.   double d;
  89.   struct { LJ_ENDIAN_LOHI(float f; , float g;) };
  90. } FPRArg;

  91. #else
  92. #error "Missing calling convention definitions for this architecture"
  93. #endif

  94. #ifndef CCALL_SPS_EXTRA
  95. #define CCALL_SPS_EXTRA                0
  96. #endif
  97. #ifndef CCALL_VECTOR_REG
  98. #define CCALL_VECTOR_REG        0
  99. #endif
  100. #ifndef CCALL_ALIGN_STACKARG
  101. #define CCALL_ALIGN_STACKARG        1
  102. #endif
  103. #ifndef CCALL_ALIGN_CALLSTATE
  104. #define CCALL_ALIGN_CALLSTATE        8
  105. #endif

  106. #define CCALL_NUM_GPR \
  107.   (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
  108. #define CCALL_NUM_FPR \
  109.   (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)

  110. /* Check against constants in lj_ctype.h. */
  111. LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
  112. LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);

  113. #define CCALL_MAXSTACK                32

  114. /* -- C call state -------------------------------------------------------- */

  115. typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
  116.   void (*func)(void);                /* Pointer to called function. */
  117.   uint32_t spadj;                /* Stack pointer adjustment. */
  118.   uint8_t nsp;                        /* Number of stack slots. */
  119.   uint8_t retref;                /* Return value by reference. */
  120. #if LJ_TARGET_X64
  121.   uint8_t ngpr;                        /* Number of arguments in GPRs. */
  122.   uint8_t nfpr;                        /* Number of arguments in FPRs. */
  123. #elif LJ_TARGET_X86
  124.   uint8_t resx87;                /* Result on x87 stack: 1:float, 2:double. */
  125. #elif LJ_TARGET_ARM64
  126.   void *retp;                        /* Aggregate return pointer in x8. */
  127. #elif LJ_TARGET_PPC
  128.   uint8_t nfpr;                        /* Number of arguments in FPRs. */
  129. #endif
  130. #if LJ_32
  131.   int32_t align1;
  132. #endif
  133. #if CCALL_NUM_FPR
  134.   FPRArg fpr[CCALL_NUM_FPR];        /* Arguments/results in FPRs. */
  135. #endif
  136.   GPRArg gpr[CCALL_NUM_GPR];        /* Arguments/results in GPRs. */
  137.   GPRArg stack[CCALL_MAXSTACK];        /* Stack slots. */
  138. } CCallState;

  139. /* -- C call handling ----------------------------------------------------- */

  140. /* Really belongs to lj_vm.h. */
  141. LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);

  142. LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
  143. LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);

  144. #endif

  145. #endif