/
ia32abi.h
88 lines (83 loc) · 3.5 KB
/
ia32abi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* platforms/Cross/plugins/IA32ABI/ia32abi.h
*
* Written by Eliot Miranda 11/2007.
* Updated 5/2011 to cope with Cog stack direction.
*
* Call foreign functions returning results in either %eax, %edx (Integral)
* or %f0 (Float, Double).
*
* The primitive will have signatures of the form
*
* <Anywhere> primFFIResult: result <Alien> call: functionAddress <Alien>
* with: firstArg <Alien> ... with: lastArg <Alien>
* <primitive: 'primCallOutXXX' module: 'IA32ABI'>
*
* result <Alien> primFFICall: functionAddress <Alien>
* with: firstArg <Alien> ... with: lastArg <Alien>
* <primitive: 'primCallOutXXX' module: 'IA32ABI'>
*
* functionAddress <Alien> primFFICallResult: result <Alien>
* with: firstArg <Alien> ... with: lastArg <Alien>
* <primitive: 'primCallOutXXX' module: 'IA32ABI'>
*
* N.B. In Cog Stack and Cogit VMs numArgs is negative to access args from
* the downward-growing stack.
*/
#define SIGNATURE sqInt *argVector/* call args on stack or in array */, \
int numArgs, /* arg count of function to call (*) */ \
int funcOffset, /* stack offset of func Alien */ \
int resultOffset/* stack offset of result Alien */
extern sqInt callIA32IntegralReturn(SIGNATURE);
extern sqInt callIA32FloatReturn (SIGNATURE);
extern sqInt callIA32DoubleReturn (SIGNATURE);
#define thunkEntryType long
#if defined(i386) || defined(__i386) || defined(__i386__) || (defined(_WIN32) && !defined(_WIN64)) || defined(_M_IX86)
# define INT_REG_ARGS /* none */
# define DBL_REG_ARGS /* none */
#elif _WIN64 || defined(_M_X64) || defined(_M_AMD64) || defined(_WIN64)
# undef thunkEntryType
# define thunkEntryType long long
# define INT_REG_ARGS long long,long long,long long,long long,
# define DBL_REG_ARGS /* double,double,double,double, NOT INCLUDED because only 4 parameters are passed in registers, either int or float */
#elif defined(__amd64__) || defined(__x86_64__) || defined(__amd64) || defined(__x86_64)
# define INT_REG_ARGS long,long,long,long,long,long,
# define DBL_REG_ARGS double,double,double,double,double,double,double,double,
#elif defined(__powerpc__) || defined(PPC) || defined(_POWER) || defined(_IBMR2) || defined(__ppc__)
# define INT_REG_ARGS long,long,long,long,long,long,long,long,
# define DBL_REG_ARGS /* none */
#elif defined(__ARM_ARCH_ISA_A64) || defined(__arm64__) || defined(__aarch64__) || defined(ARM64)
# undef thunkEntryType
# define thunkEntryType long long
# define INT_REG_ARGS long,long,long,long,long,long,long,long,
# define DBL_REG_ARGS double,double,double,double,double,double,double,double,
#elif defined(__ARM_ARCH__) || defined(__arm__) || defined(__arm32__) || defined(ARM32)
# undef thunkEntryType
# define thunkEntryType long long
# define INT_REG_ARGS long,long,long,long,
# define DBL_REG_ARGS double,double,double,double,double,double,double,double,
#endif
extern thunkEntryType thunkEntry (INT_REG_ARGS DBL_REG_ARGS void *,sqIntptr_t *);
extern void *allocateExecutablePage(long *pagesize);
extern VMCallbackContext *getMostRecentCallbackContext(void);
#undef thunkEntryType
/* Use the most minimal setjmp/longjmp pair available; no signal handling
* wanted or necessary.
*/
#if !defined(_WIN32)
# undef setjmp
# undef longjmp
# define setjmp _setjmp
# define longjmp _longjmp
#endif
/* Note: on windows 64 via mingw-w64, the 2nd argument NULL to _setjmp prevents stack unwinding
*/
#if defined(_WIN64)
# undef setjmp
# undef longjmp
# if defined(__GNUC__)
# define setjmp(jb) _setjmp(jb,NULL)
# elif defined(_MSC_VER)
# define setjmp(jb) _setjmp(jb)
# endif
#endif