(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
x86_64/
abi/
avx512fp16/
m256h/
args.h
       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 ymm0
      24  #define F1 ymm1
      25  #define F2 ymm2
      26  #define F3 ymm3
      27  #define F4 ymm4
      28  #define F5 ymm5
      29  #define F6 ymm6
      30  #define F7 ymm7
      31  
      32  typedef union {
      33    _Float16 __Float16[16];
      34    float _float[8];
      35    double _double[4];
      36    long long _longlong[4];
      37    int _int[8];
      38    unsigned long long _ulonglong[4];
      39    __m64 _m64[4];
      40    __m128 _m128[2];
      41    __m256 _m256[1];
      42    __m256h _m256h[1];
      43  } YMM_T;
      44  
      45  typedef union {
      46    float _float;
      47    double _double;
      48    long double _ldouble;
      49    unsigned long long _ulonglong[2];
      50  } X87_T;
      51  extern void (*callthis)(void);
      52  extern unsigned long long rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp,r8,r9,r10,r11,r12,r13,r14,r15;
      53  YMM_T ymm_regs[16];
      54  X87_T x87_regs[8];
      55  extern volatile unsigned long long volatile_var;
      56  extern void snapshot (void);
      57  extern void snapshot_ret (void);
      58  #define WRAP_CALL(N) \
      59    (callthis = (void (*)()) (N), (typeof (&N)) snapshot)
      60  #define WRAP_RET(N) \
      61    (callthis = (void (*)()) (N), (typeof (&N)) snapshot_ret)
      62  
      63  /* Clear all integer registers.  */
      64  #define clear_int_hardware_registers \
      65    asm __volatile__ ("xor %%rax, %%rax\n\t" \
      66  		    "xor %%rbx, %%rbx\n\t" \
      67  		    "xor %%rcx, %%rcx\n\t" \
      68  		    "xor %%rdx, %%rdx\n\t" \
      69  		    "xor %%rsi, %%rsi\n\t" \
      70  		    "xor %%rdi, %%rdi\n\t" \
      71  		    "xor %%r8, %%r8\n\t" \
      72  		    "xor %%r9, %%r9\n\t" \
      73  		    "xor %%r10, %%r10\n\t" \
      74  		    "xor %%r11, %%r11\n\t" \
      75  		    "xor %%r12, %%r12\n\t" \
      76  		    "xor %%r13, %%r13\n\t" \
      77  		    "xor %%r14, %%r14\n\t" \
      78  		    "xor %%r15, %%r15\n\t" \
      79  		    ::: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", \
      80  		    "r9", "r10", "r11", "r12", "r13", "r14", "r15");
      81  
      82  /* This is the list of registers available for passing arguments. Not all of
      83     these are used or even really available.  */
      84  struct IntegerRegisters
      85  {
      86    unsigned long long rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;
      87  };
      88  struct FloatRegisters
      89  {
      90    double mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
      91    long double st0, st1, st2, st3, st4, st5, st6, st7;
      92    YMM_T ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, ymm8, ymm9,
      93          ymm10, ymm11, ymm12, ymm13, ymm14, ymm15;
      94  };
      95  
      96  /* Implemented in scalarargs.c  */
      97  extern struct IntegerRegisters iregs;
      98  extern struct FloatRegisters fregs;
      99  extern unsigned int num_iregs, num_fregs;
     100  
     101  #define check_int_arguments do { \
     102    assert (num_iregs <= 0 || iregs.I0 == I0); \
     103    assert (num_iregs <= 1 || iregs.I1 == I1); \
     104    assert (num_iregs <= 2 || iregs.I2 == I2); \
     105    assert (num_iregs <= 3 || iregs.I3 == I3); \
     106    assert (num_iregs <= 4 || iregs.I4 == I4); \
     107    assert (num_iregs <= 5 || iregs.I5 == I5); \
     108    } while (0)
     109  
     110  #define check_char_arguments check_int_arguments
     111  #define check_short_arguments check_int_arguments
     112  #define check_long_arguments check_int_arguments
     113  
     114  /* Clear register struct.  */
     115  #define clear_struct_registers \
     116    rax = rbx = rcx = rdx = rdi = rsi = rbp = rsp \
     117      = r8 = r9 = r10 = r11 = r12 = r13 = r14 = r15 = 0; \
     118    memset (&iregs, 0, sizeof (iregs)); \
     119    memset (&fregs, 0, sizeof (fregs)); \
     120    memset (ymm_regs, 0, sizeof (ymm_regs)); \
     121    memset (x87_regs, 0, sizeof (x87_regs));
     122  
     123  /* Clear both hardware and register structs for integers.  */
     124  #define clear_int_registers \
     125    clear_struct_registers \
     126    clear_int_hardware_registers
     127  
     128  /* TODO: Do the checking.  */
     129  #define check_f_arguments(T) do { \
     130    assert (num_fregs <= 0 || fregs.ymm0._ ## T [0] == ymm_regs[0]._ ## T [0]); \
     131    assert (num_fregs <= 1 || fregs.ymm1._ ## T [0] == ymm_regs[1]._ ## T [0]); \
     132    assert (num_fregs <= 2 || fregs.ymm2._ ## T [0] == ymm_regs[2]._ ## T [0]); \
     133    assert (num_fregs <= 3 || fregs.ymm3._ ## T [0] == ymm_regs[3]._ ## T [0]); \
     134    assert (num_fregs <= 4 || fregs.ymm4._ ## T [0] == ymm_regs[4]._ ## T [0]); \
     135    assert (num_fregs <= 5 || fregs.ymm5._ ## T [0] == ymm_regs[5]._ ## T [0]); \
     136    assert (num_fregs <= 6 || fregs.ymm6._ ## T [0] == ymm_regs[6]._ ## T [0]); \
     137    assert (num_fregs <= 7 || fregs.ymm7._ ## T [0] == ymm_regs[7]._ ## T [0]); \
     138    } while (0)
     139  
     140  #define check_float_arguments check_f_arguments(float)
     141  #define check_double_arguments check_f_arguments(double)
     142  
     143  #define check_vector_arguments(T,O) do { \
     144    assert (num_fregs <= 0 \
     145  	  || memcmp (((char *) &fregs.ymm0) + (O), \
     146  		     &ymm_regs[0], \
     147  		     sizeof (__ ## T) - (O)) == 0); \
     148    assert (num_fregs <= 1 \
     149  	  || memcmp (((char *) &fregs.ymm1) + (O), \
     150  		     &ymm_regs[1], \
     151  		     sizeof (__ ## T) - (O)) == 0); \
     152    assert (num_fregs <= 2 \
     153  	  || memcmp (((char *) &fregs.ymm2) + (O), \
     154  		     &ymm_regs[2], \
     155  		     sizeof (__ ## T) - (O)) == 0); \
     156    assert (num_fregs <= 3 \
     157  	  || memcmp (((char *) &fregs.ymm3) + (O), \
     158  		     &ymm_regs[3], \
     159  		     sizeof (__ ## T) - (O)) == 0); \
     160    assert (num_fregs <= 4 \
     161  	  || memcmp (((char *) &fregs.ymm4) + (O), \
     162  		     &ymm_regs[4], \
     163  		     sizeof (__ ## T) - (O)) == 0); \
     164    assert (num_fregs <= 5 \
     165  	  || memcmp (((char *) &fregs.ymm5) + (O), \
     166  		     &ymm_regs[5], \
     167  		     sizeof (__ ## T) - (O)) == 0); \
     168    assert (num_fregs <= 6 \
     169  	  || memcmp (((char *) &fregs.ymm6) + (O), \
     170  		     &ymm_regs[6], \
     171  		     sizeof (__ ## T) - (O)) == 0); \
     172    assert (num_fregs <= 7 \
     173  	  || memcmp (((char *) &fregs.ymm7) + (O), \
     174  		     &ymm_regs[7], \
     175  		     sizeof (__ ## T) - (O)) == 0); \
     176    } while (0)
     177  
     178  #define check_m64_arguments check_vector_arguments(m64, 0)
     179  #define check_m128_arguments check_vector_arguments(m128, 0)
     180  #define check_m256_arguments check_vector_arguments(m256, 0)
     181  
     182  #endif /* INCLUDED_ARGS_H  */