lj_ccall.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. ** FFI C call handling.
  3. ** Copyright (C) 2005-2014 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_PPC
  59. #define CCALL_NARG_GPR 8
  60. #define CCALL_NARG_FPR 8
  61. #define CCALL_NRET_GPR 4 /* For complex double. */
  62. #define CCALL_NRET_FPR 1
  63. #define CCALL_SPS_EXTRA 4
  64. #define CCALL_SPS_FREE 0
  65. typedef intptr_t GPRArg;
  66. typedef double FPRArg;
  67. #elif LJ_TARGET_PPCSPE
  68. #define CCALL_NARG_GPR 8
  69. #define CCALL_NARG_FPR 0
  70. #define CCALL_NRET_GPR 4 /* For softfp complex double. */
  71. #define CCALL_NRET_FPR 0
  72. #define CCALL_SPS_FREE 0 /* NYI */
  73. typedef intptr_t GPRArg;
  74. #elif LJ_TARGET_MIPS
  75. #define CCALL_NARG_GPR 4
  76. #define CCALL_NARG_FPR 2
  77. #define CCALL_NRET_GPR 2
  78. #define CCALL_NRET_FPR 2
  79. #define CCALL_SPS_EXTRA 7
  80. #define CCALL_SPS_FREE 1
  81. typedef intptr_t GPRArg;
  82. typedef union FPRArg {
  83. double d;
  84. struct { LJ_ENDIAN_LOHI(float f; , float g;) };
  85. } FPRArg;
  86. #else
  87. #error "Missing calling convention definitions for this architecture"
  88. #endif
  89. #ifndef CCALL_SPS_EXTRA
  90. #define CCALL_SPS_EXTRA 0
  91. #endif
  92. #ifndef CCALL_VECTOR_REG
  93. #define CCALL_VECTOR_REG 0
  94. #endif
  95. #ifndef CCALL_ALIGN_STACKARG
  96. #define CCALL_ALIGN_STACKARG 1
  97. #endif
  98. #ifndef CCALL_ALIGN_CALLSTATE
  99. #define CCALL_ALIGN_CALLSTATE 8
  100. #endif
  101. #define CCALL_NUM_GPR \
  102. (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
  103. #define CCALL_NUM_FPR \
  104. (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
  105. /* Check against constants in lj_ctype.h. */
  106. LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
  107. LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
  108. #define CCALL_MAXSTACK 32
  109. /* -- C call state -------------------------------------------------------- */
  110. typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
  111. void (*func)(void); /* Pointer to called function. */
  112. uint32_t spadj; /* Stack pointer adjustment. */
  113. uint8_t nsp; /* Number of stack slots. */
  114. uint8_t retref; /* Return value by reference. */
  115. #if LJ_TARGET_X64
  116. uint8_t ngpr; /* Number of arguments in GPRs. */
  117. uint8_t nfpr; /* Number of arguments in FPRs. */
  118. #elif LJ_TARGET_X86
  119. uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
  120. #elif LJ_TARGET_PPC
  121. uint8_t nfpr; /* Number of arguments in FPRs. */
  122. #endif
  123. #if LJ_32
  124. int32_t align1;
  125. #endif
  126. #if CCALL_NUM_FPR
  127. FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
  128. #endif
  129. GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
  130. GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
  131. } CCallState;
  132. /* -- C call handling ----------------------------------------------------- */
  133. /* Really belongs to lj_vm.h. */
  134. LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
  135. LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
  136. LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
  137. #endif
  138. #endif