16
16
#ifdef CONFIG_X86_64
18
/* Windows functions must have 32 bytes of shadow space for arguments
19
* above return address, irrespective of number of args. So argc >= 4
22
#define alloc_win_stack_frame(argc) \
23
"sub $(" #argc "+1)*8, %%rsp\n\t"
24
#define free_win_stack_frame(argc) \
25
"add $(" #argc "+1)*8, %%rsp\n\t"
27
/* m is index of Windows arg required; Windows arg 1 should be at
28
* 0(%rsp), arg 2 at 8(%rsp) and so on after the frame is allocated.
31
#define lin2win_win_arg(m) "(" #m "-1)*8(%%rsp)"
33
/* args for Windows function must be in clobber / output list */
36
"=a" (_ret), "=c" (_dummy), "=d" (_dummy), \
37
"=r" (r8), "=r" (r9), "=r" (r10), "=r" (r11)
39
#define clobbers() "cc"
18
u64 lin2win0(void *func);
19
u64 lin2win1(void *func, u64 arg1);
20
u64 lin2win2(void *func, u64 arg1, u64 arg2);
21
u64 lin2win3(void *func, u64 arg1, u64 arg2, u64 arg3);
22
u64 lin2win4(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4);
23
u64 lin2win5(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5);
24
u64 lin2win6(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5,
41
27
#define LIN2WIN0(func) \
44
register u64 r8 __asm__("r8"); \
45
register u64 r9 __asm__("r9"); \
46
register u64 r10 __asm__("r10"); \
47
register u64 r11 __asm__("r11"); \
48
__asm__ __volatile__( \
49
alloc_win_stack_frame(4) \
50
"callq *%[fptr]\n\t" \
51
free_win_stack_frame(4) \
58
34
#define LIN2WIN1(func, arg1) \
61
register u64 r8 __asm__("r8"); \
62
register u64 r9 __asm__("r9"); \
63
register u64 r10 __asm__("r10"); \
64
register u64 r11 __asm__("r11"); \
65
__asm__ __volatile__( \
66
alloc_win_stack_frame(4) \
67
"callq *%[fptr]\n\t" \
68
free_win_stack_frame(4) \
70
: "c" (arg1), [fptr] "r" (func) \
38
lin2win1(func, (u64)arg1); \
75
41
#define LIN2WIN2(func, arg1, arg2) \
78
register u64 r8 __asm__("r8"); \
79
register u64 r9 __asm__("r9"); \
80
register u64 r10 __asm__("r10"); \
81
register u64 r11 __asm__("r11"); \
82
__asm__ __volatile__( \
83
alloc_win_stack_frame(4) \
84
"callq *%[fptr]\n\t" \
85
free_win_stack_frame(4) \
87
: "c" (arg1), "d" (arg2), [fptr] "r" (func) \
45
lin2win2(func, (u64)arg1, (u64)arg2); \
92
48
#define LIN2WIN3(func, arg1, arg2, arg3) \
95
register u64 r8 __asm__("r8") = (u64)arg3; \
96
register u64 r9 __asm__("r9"); \
97
register u64 r10 __asm__("r10"); \
98
register u64 r11 __asm__("r11"); \
99
__asm__ __volatile__( \
100
alloc_win_stack_frame(4) \
101
"callq *%[fptr]\n\t" \
102
free_win_stack_frame(4) \
104
: "c" (arg1), "d" (arg2), "r" (r8), \
51
func(arg1, arg2, arg3); \
52
lin2win3(func, (u64)arg1, (u64)arg2, (u64)arg3); \
110
55
#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \
113
register u64 r8 __asm__("r8") = (u64)arg3; \
114
register u64 r9 __asm__("r9") = (u64)arg4; \
115
register u64 r10 __asm__("r10"); \
116
register u64 r11 __asm__("r11"); \
117
__asm__ __volatile__( \
118
alloc_win_stack_frame(4) \
119
"callq *%[fptr]\n\t" \
120
free_win_stack_frame(4) \
122
: "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
58
func(arg1, arg2, arg3, arg4); \
59
lin2win4(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4); \
128
62
#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \
131
register u64 r8 __asm__("r8") = (u64)arg3; \
132
register u64 r9 __asm__("r9") = (u64)arg4; \
133
register u64 r10 __asm__("r10"); \
134
register u64 r11 __asm__("r11"); \
135
__asm__ __volatile__( \
136
alloc_win_stack_frame(5) \
137
"movq %[rarg5], " lin2win_win_arg(5) "\n\t" \
138
"callq *%[fptr]\n\t" \
139
free_win_stack_frame(5) \
141
: "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
142
[rarg5] "ri" ((u64)arg5), \
65
func(arg1, arg2, arg3, arg4, arg5); \
66
lin2win5(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4, \
148
70
#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
151
register u64 r8 __asm__("r8") = (u64)arg3; \
152
register u64 r9 __asm__("r9") = (u64)arg4; \
153
register u64 r10 __asm__("r10"); \
154
register u64 r11 __asm__("r11"); \
155
__asm__ __volatile__( \
156
alloc_win_stack_frame(6) \
157
"movq %[rarg5], " lin2win_win_arg(5) "\n\t" \
158
"movq %[rarg6], " lin2win_win_arg(6) "\n\t" \
159
"callq *%[fptr]\n\t" \
160
free_win_stack_frame(6) \
162
: "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
163
[rarg5] "ri" ((u64)arg5), [rarg6] "ri" ((u64)arg6), \
73
func(arg1, arg2, arg3, arg4, arg5, arg6); \
74
lin2win6(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4, \
75
(u64)arg5, (u64)arg6); \
169
78
#else // CONFIG_X86_64