2016-04-21 15:19:32 +03:00
# ifndef __TRAMPOLINES_X86_64_H__
# define __TRAMPOLINES_X86_64_H__
# ifdef __cplusplus
extern " C " {
# endif
2019-04-23 18:53:35 +03:00
struct XamarinCallState {
2016-04-21 15:19:32 +03:00
uint64_t type ;
uint64_t rdi ; // 1st argument
2019-05-06 08:25:49 +03:00
uint64_t rsi ; // 2nd argument
2016-04-21 15:19:32 +03:00
uint64_t rdx ; // 3rd argument
uint64_t rcx ; // 4th argument
uint64_t r8 ; // 5th argument
uint64_t r9 ; // 6th argument
uint64_t rbp ;
2019-05-06 08:25:49 +03:00
uint64_t rax ;
uint64_t rdx_out ; // use this field as a temporary rdx field to store output. It makes the marshalling code a bit easier to have this field just after the rax field (so we can treat rax+rdx as a continuous block of 32 bytes of memory)
2016-04-21 15:19:32 +03:00
long double xmm0 ;
long double xmm1 ;
long double xmm2 ;
long double xmm3 ;
long double xmm4 ;
long double xmm5 ;
long double xmm6 ;
long double xmm7 ;
2019-04-23 08:29:20 +03:00
bool is_stret ( ) { return ( type & Tramp_Stret ) = = Tramp_Stret ; }
id self ( ) { return is_stret ( ) ? ( id ) rsi : ( id ) rdi ; }
SEL sel ( ) { return is_stret ( ) ? ( SEL ) rdx : ( SEL ) rsi ; }
2016-04-21 15:19:32 +03:00
} ;
struct ParamIterator {
2019-04-23 18:53:35 +03:00
struct XamarinCallState * state ;
2016-04-21 15:19:32 +03:00
int byte_count ;
int float_count ;
uint8_t * stack_next ;
} ;
2019-04-23 18:53:35 +03:00
void xamarin_arch_trampoline ( struct XamarinCallState * state ) ;
2016-04-21 15:19:32 +03:00
# ifdef __cplusplus
} /* extern "C" */
# endif
# endif /* __TRAMPOLINES_X86_64_H__ */