1 #ifndef INCLUDED_ARGS_H 2 #define INCLUDED_ARGS_H 3 4 #include <immintrin.h> 5 #include <string.h> 6 7 /* Assertion macro. */ 8 #define assert(test) if (!(test)) abort() 9 10 #ifdef __GNUC__ 11 #define ATTRIBUTE_UNUSED __attribute__((__unused__)) 12 #else 13 #define ATTRIBUTE_UNUSED 14 #endif 15 16 /* This defines the calling sequences for integers and floats. */ 17 #define I0 rdi 18 #define I1 rsi 19 #define I2 rdx 20 #define I3 rcx 21 #define I4 r8 22 #define I5 r9 23 #define F0 zmm0 24 #define F1 zmm1 25 #define F2 zmm2 26 #define F3 zmm3 27 #define F4 zmm4 28 #define F5 zmm5 29 #define F6 zmm6 30 #define F7 zmm7 31 32 typedef union { 33 float _float[16]; 34 double _double[8]; 35 long _long[8]; 36 int _int[16]; 37 unsigned long _ulong[8]; 38 __m64 _m64[8]; 39 __m128 _m128[4]; 40 __m256 _m256[2]; 41 __m512 _m512[1]; 42 } ZMM_T; 43 44 typedef union { 45 float _float; 46 double _double; 47 long double _ldouble; 48 unsigned long _ulong[2]; 49 } X87_T; 50 extern void (*callthis)(void); 51 extern unsigned long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15; 52 ZMM_T zmm_regs[32]; 53 X87_T x87_regs[8]; 54 extern volatile unsigned long volatile_var; 55 extern void snapshot (void); 56 extern void snapshot_ret (void); 57 #define WRAP_CALL(N) \ 58 (callthis = (void (*)()) (N), (typeof (&N)) snapshot) 59 #define WRAP_RET(N) \ 60 (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret) 61 62 /* Clear all integer registers. */ 63 #define clear_int_hardware_registers \ 64 asm __volatile__ ("xor %%rax, %%rax\n\t" \ 65 "xor %%rbx, %%rbx\n\t" \ 66 "xor %%rcx, %%rcx\n\t" \ 67 "xor %%rdx, %%rdx\n\t" \ 68 "xor %%rsi, %%rsi\n\t" \ 69 "xor %%rdi, %%rdi\n\t" \ 70 "xor %%r8, %%r8\n\t" \ 71 "xor %%r9, %%r9\n\t" \ 72 "xor %%r10, %%r10\n\t" \ 73 "xor %%r11, %%r11\n\t" \ 74 "xor %%r12, %%r12\n\t" \ 75 "xor %%r13, %%r13\n\t" \ 76 "xor %%r14, %%r14\n\t" \ 77 "xor %%r15, %%r15\n\t" \ 78 ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \ 79 "r9", "r10", "r11", "r12", "r13", "r14", "r15"); 80 81 /* This is the list of registers available for passing arguments. Not all of 82 these are used or even really available. */ 83 struct IntegerRegisters 84 { 85 unsigned long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; 86 }; 87 struct FloatRegisters 88 { 89 double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7; 90 long double st0, st1, st2, st3, st4, st5, st6, st7; 91 ZMM_T zmm0, zmm1, zmm2, zmm3, zmm4, zmm5, zmm6, zmm7, zmm8, zmm9, 92 zmm10, zmm11, zmm12, zmm13, zmm14, zmm15, zmm16, zmm17, zmm18, 93 zmm19, zmm20, zmm21, zmm22, zmm23, zmm24, zmm25, zmm26, zmm27, 94 zmm28, zmm29, zmm30, zmm31; 95 }; 96 97 /* Implemented in scalarargs.c */ 98 extern struct IntegerRegisters iregs; 99 extern struct FloatRegisters fregs; 100 extern unsigned int num_iregs, num_fregs; 101 102 #define check_int_arguments do { \ 103 assert (num_iregs <= 0 || iregs.I0 == I0); \ 104 assert (num_iregs <= 1 || iregs.I1 == I1); \ 105 assert (num_iregs <= 2 || iregs.I2 == I2); \ 106 assert (num_iregs <= 3 || iregs.I3 == I3); \ 107 assert (num_iregs <= 4 || iregs.I4 == I4); \ 108 assert (num_iregs <= 5 || iregs.I5 == I5); \ 109 } while (0) 110 111 #define check_char_arguments check_int_arguments 112 #define check_short_arguments check_int_arguments 113 #define check_long_arguments check_int_arguments 114 115 /* Clear register struct. */ 116 #define clear_struct_registers \ 117 rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \ 118 = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \ 119 memset (&iregs, 0, sizeof (iregs)); \ 120 memset (&fregs, 0, sizeof (fregs)); \ 121 memset (zmm_regs, 0, sizeof (zmm_regs)); \ 122 memset (x87_regs, 0, sizeof (x87_regs)); 123 124 /* Clear both hardware and register structs for integers. */ 125 #define clear_int_registers \ 126 clear_struct_registers \ 127 clear_int_hardware_registers 128 129 /* TODO: Do the checking. */ 130 #define check_f_arguments(T) do { \ 131 assert (num_fregs <= 0 || fregs.zmm0._ ## T [0] == zmm_regs[0]._ ## T [0]); \ 132 assert (num_fregs <= 1 || fregs.zmm1._ ## T [0] == zmm_regs[1]._ ## T [0]); \ 133 assert (num_fregs <= 2 || fregs.zmm2._ ## T [0] == zmm_regs[2]._ ## T [0]); \ 134 assert (num_fregs <= 3 || fregs.zmm3._ ## T [0] == zmm_regs[3]._ ## T [0]); \ 135 assert (num_fregs <= 4 || fregs.zmm4._ ## T [0] == zmm_regs[4]._ ## T [0]); \ 136 assert (num_fregs <= 5 || fregs.zmm5._ ## T [0] == zmm_regs[5]._ ## T [0]); \ 137 assert (num_fregs <= 6 || fregs.zmm6._ ## T [0] == zmm_regs[6]._ ## T [0]); \ 138 assert (num_fregs <= 7 || fregs.zmm7._ ## T [0] == zmm_regs[7]._ ## T [0]); \ 139 } while (0) 140 141 #define check_float_arguments check_f_arguments(float) 142 #define check_double_arguments check_f_arguments(double) 143 144 #define check_vector_arguments(T,O) do { \ 145 assert (num_fregs <= 0 \ 146 || memcmp (((char *) &fregs.zmm0) + (O), \ 147 &zmm_regs[0], \ 148 sizeof (__ ## T) - (O)) == 0); \ 149 assert (num_fregs <= 1 \ 150 || memcmp (((char *) &fregs.zmm1) + (O), \ 151 &zmm_regs[1], \ 152 sizeof (__ ## T) - (O)) == 0); \ 153 assert (num_fregs <= 2 \ 154 || memcmp (((char *) &fregs.zmm2) + (O), \ 155 &zmm_regs[2], \ 156 sizeof (__ ## T) - (O)) == 0); \ 157 assert (num_fregs <= 3 \ 158 || memcmp (((char *) &fregs.zmm3) + (O), \ 159 &zmm_regs[3], \ 160 sizeof (__ ## T) - (O)) == 0); \ 161 assert (num_fregs <= 4 \ 162 || memcmp (((char *) &fregs.zmm4) + (O), \ 163 &zmm_regs[4], \ 164 sizeof (__ ## T) - (O)) == 0); \ 165 assert (num_fregs <= 5 \ 166 || memcmp (((char *) &fregs.zmm5) + (O), \ 167 &zmm_regs[5], \ 168 sizeof (__ ## T) - (O)) == 0); \ 169 assert (num_fregs <= 6 \ 170 || memcmp (((char *) &fregs.zmm6) + (O), \ 171 &zmm_regs[6], \ 172 sizeof (__ ## T) - (O)) == 0); \ 173 assert (num_fregs <= 7 \ 174 || memcmp (((char *) &fregs.zmm7) + (O), \ 175 &zmm_regs[7], \ 176 sizeof (__ ## T) - (O)) == 0); \ 177 } while (0) 178 179 #define check_m64_arguments check_vector_arguments(m64, 0) 180 #define check_m128_arguments check_vector_arguments(m128, 0) 181 #define check_m256_arguments check_vector_arguments(m256, 0) 182 #define check_m512_arguments check_vector_arguments(m512, 0) 183 184 #endif /* INCLUDED_ARGS_H */ 185