1 #ifndef INCLUDED_ARGS_H
2 #define INCLUDED_ARGS_H
8 #define assert(test) if (!(test)) abort()
11 #define ATTRIBUTE_UNUSED __attribute__((__unused__))
13 #define ATTRIBUTE_UNUSED
16 /* This defines the calling sequences for integers and floats. */
37 unsigned long _ulong
[4];
47 unsigned long _ulong
[2];
49 extern void (*callthis
)(void);
50 extern unsigned long rax
,rbx
,rcx
,rdx
,rsi
,rdi
,rsp
,rbp
,r8
,r9
,r10
,r11
,r12
,r13
,r14
,r15
;
53 extern volatile unsigned long volatile_var
;
54 extern void snapshot (void);
55 extern void snapshot_ret (void);
56 #define WRAP_CALL(N) \
57 (callthis = (void (*)()) (N), (typeof (&N)) snapshot)
59 (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret)
61 /* Clear all integer registers. */
62 #define clear_int_hardware_registers \
63 asm __volatile__ ("xor %%rax, %%rax\n\t" \
64 "xor %%rbx, %%rbx\n\t" \
65 "xor %%rcx, %%rcx\n\t" \
66 "xor %%rdx, %%rdx\n\t" \
67 "xor %%rsi, %%rsi\n\t" \
68 "xor %%rdi, %%rdi\n\t" \
69 "xor %%r8, %%r8\n\t" \
70 "xor %%r9, %%r9\n\t" \
71 "xor %%r10, %%r10\n\t" \
72 "xor %%r11, %%r11\n\t" \
73 "xor %%r12, %%r12\n\t" \
74 "xor %%r13, %%r13\n\t" \
75 "xor %%r14, %%r14\n\t" \
76 "xor %%r15, %%r15\n\t" \
77 ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \
78 "r9", "r10", "r11", "r12", "r13", "r14", "r15");
80 /* This is the list of registers available for passing arguments. Not all of
81 these are used or even really available. */
82 struct IntegerRegisters
84 unsigned long rax
, rbx
, rcx
, rdx
, rsi
, rdi
, r8
, r9
, r10
, r11
, r12
, r13
, r14
, r15
;
88 double mm0
, mm1
, mm2
, mm3
, mm4
, mm5
, mm6
, mm7
;
89 long double st0
, st1
, st2
, st3
, st4
, st5
, st6
, st7
;
90 YMM_T ymm0
, ymm1
, ymm2
, ymm3
, ymm4
, ymm5
, ymm6
, ymm7
, ymm8
, ymm9
,
91 ymm10
, ymm11
, ymm12
, ymm13
, ymm14
, ymm15
;
94 /* Implemented in scalarargs.c */
95 extern struct IntegerRegisters iregs
;
96 extern struct FloatRegisters fregs
;
97 extern unsigned int num_iregs
, num_fregs
;
99 #define check_int_arguments do { \
100 assert (num_iregs <= 0 || iregs.I0 == I0); \
101 assert (num_iregs <= 1 || iregs.I1 == I1); \
102 assert (num_iregs <= 2 || iregs.I2 == I2); \
103 assert (num_iregs <= 3 || iregs.I3 == I3); \
104 assert (num_iregs <= 4 || iregs.I4 == I4); \
105 assert (num_iregs <= 5 || iregs.I5 == I5); \
108 #define check_char_arguments check_int_arguments
109 #define check_short_arguments check_int_arguments
110 #define check_long_arguments check_int_arguments
112 /* Clear register struct. */
113 #define clear_struct_registers \
114 rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \
115 = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \
116 memset (&iregs, 0, sizeof (iregs)); \
117 memset (&fregs, 0, sizeof (fregs)); \
118 memset (ymm_regs, 0, sizeof (ymm_regs)); \
119 memset (x87_regs, 0, sizeof (x87_regs));
121 /* Clear both hardware and register structs for integers. */
122 #define clear_int_registers \
123 clear_struct_registers \
124 clear_int_hardware_registers
126 /* TODO: Do the checking. */
127 #define check_f_arguments(T) do { \
128 assert (num_fregs <= 0 || fregs.ymm0._ ## T [0] == ymm_regs[0]._ ## T [0]); \
129 assert (num_fregs <= 1 || fregs.ymm1._ ## T [0] == ymm_regs[1]._ ## T [0]); \
130 assert (num_fregs <= 2 || fregs.ymm2._ ## T [0] == ymm_regs[2]._ ## T [0]); \
131 assert (num_fregs <= 3 || fregs.ymm3._ ## T [0] == ymm_regs[3]._ ## T [0]); \
132 assert (num_fregs <= 4 || fregs.ymm4._ ## T [0] == ymm_regs[4]._ ## T [0]); \
133 assert (num_fregs <= 5 || fregs.ymm5._ ## T [0] == ymm_regs[5]._ ## T [0]); \
134 assert (num_fregs <= 6 || fregs.ymm6._ ## T [0] == ymm_regs[6]._ ## T [0]); \
135 assert (num_fregs <= 7 || fregs.ymm7._ ## T [0] == ymm_regs[7]._ ## T [0]); \
138 #define check_float_arguments check_f_arguments(float)
139 #define check_double_arguments check_f_arguments(double)
141 #define check_vector_arguments(T,O) do { \
142 assert (num_fregs <= 0 \
143 || memcmp (((char *) &fregs.ymm0) + (O), \
145 sizeof (__ ## T) - (O)) == 0); \
146 assert (num_fregs <= 1 \
147 || memcmp (((char *) &fregs.ymm1) + (O), \
149 sizeof (__ ## T) - (O)) == 0); \
150 assert (num_fregs <= 2 \
151 || memcmp (((char *) &fregs.ymm2) + (O), \
153 sizeof (__ ## T) - (O)) == 0); \
154 assert (num_fregs <= 3 \
155 || memcmp (((char *) &fregs.ymm3) + (O), \
157 sizeof (__ ## T) - (O)) == 0); \
158 assert (num_fregs <= 4 \
159 || memcmp (((char *) &fregs.ymm4) + (O), \
161 sizeof (__ ## T) - (O)) == 0); \
162 assert (num_fregs <= 5 \
163 || memcmp (((char *) &fregs.ymm5) + (O), \
165 sizeof (__ ## T) - (O)) == 0); \
166 assert (num_fregs <= 6 \
167 || memcmp (((char *) &fregs.ymm6) + (O), \
169 sizeof (__ ## T) - (O)) == 0); \
170 assert (num_fregs <= 7 \
171 || memcmp (((char *) &fregs.ymm7) + (O), \
173 sizeof (__ ## T) - (O)) == 0); \
176 #define check_m64_arguments check_vector_arguments(m64, 0)
177 #define check_m128_arguments check_vector_arguments(m128, 0)
178 #define check_m256_arguments check_vector_arguments(m256, 0)
180 #endif /* INCLUDED_ARGS_H */