(root)/
gcc-13.2.0/
gcc/
testsuite/
jit.dg/
test-alignment.c
       1  #include <stdlib.h>
       2  #include <stdio.h>
       3  
       4  #include "libgccjit.h"
       5  
       6  #include "harness.h"
       7  
       8  struct s2
       9  {
      10    char x __attribute__ ((aligned (2)));
      11    char y __attribute__ ((aligned (2)));
      12  };
      13  
      14  struct s4
      15  {
      16    char x __attribute__ ((aligned (4)));
      17    char y __attribute__ ((aligned (4)));
      18  };
      19  
      20  struct s8
      21  {
      22    char x __attribute__ ((aligned (8)));
      23    char y __attribute__ ((aligned (8)));
      24  };
      25  
      26  struct s16
      27  {
      28    char x __attribute__ ((aligned (16)));
      29    char y __attribute__ ((aligned (16)));
      30  };
      31  
      32  struct s32
      33  {
      34    char x __attribute__ ((aligned (32)));
      35    char y __attribute__ ((aligned (32)));
      36  };
      37  
      38  struct s64
      39  {
      40    char x __attribute__ ((aligned (64)));
      41    char y __attribute__ ((aligned (64)));
      42  };
      43  
      44  struct s128
      45  {
      46    char x __attribute__ ((aligned (128)));
      47    char y __attribute__ ((aligned (128)));
      48  };
      49  
      50  static void
      51  create_aligned_code (gcc_jit_context *ctxt, const char *struct_name,
      52  		     unsigned int alignment, const char *reader_fn_name,
      53  		     const char *writer_fn_name)
      54  {
      55    /* Let's try to inject the equivalent of:
      56  
      57       char
      58       READER_FN_NAME (const struct STRUCT_NAME *f)
      59       {
      60         return f->x * f->y;
      61       }
      62  
      63       char
      64       WRITER_FN_NAME (struct STRUCT_NAME *g)
      65       {
      66         g->x = 5;
      67         g->y = 7;
      68         return READER_FN_NAME (g);
      69       }
      70    */
      71    gcc_jit_type *char_type =
      72      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
      73    gcc_jit_type *aligned_char_type =
      74      gcc_jit_type_get_aligned (char_type, alignment);
      75    gcc_jit_field *x =
      76      gcc_jit_context_new_field (ctxt,
      77                                 NULL,
      78                                 aligned_char_type,
      79                                 "x");
      80    gcc_jit_field *y =
      81      gcc_jit_context_new_field (ctxt,
      82                                 NULL,
      83                                 aligned_char_type,
      84                                 "y");
      85    gcc_jit_field *fields[] = {x, y};
      86    gcc_jit_type *struct_type =
      87      gcc_jit_struct_as_type (
      88        gcc_jit_context_new_struct_type (ctxt, NULL, struct_name, 2, fields));
      89    gcc_jit_type *const_struct_type = gcc_jit_type_get_const (struct_type);
      90    gcc_jit_type *const_ptr_type = gcc_jit_type_get_pointer (const_struct_type);
      91  
      92    /* Build the reader fn.  */
      93    gcc_jit_param *param_f =
      94      gcc_jit_context_new_param (ctxt, NULL, const_ptr_type, "f");
      95    gcc_jit_function *fn_test_reading =
      96      gcc_jit_context_new_function (ctxt, NULL,
      97                                    GCC_JIT_FUNCTION_EXPORTED,
      98                                    char_type,
      99  				  reader_fn_name,
     100                                    1, &param_f,
     101                                    0);
     102  
     103    /* return f->x * f->y; */
     104    gcc_jit_block *reading_block = gcc_jit_function_new_block (fn_test_reading, NULL);
     105    gcc_jit_block_end_with_return (
     106      reading_block,
     107      NULL,
     108      gcc_jit_context_new_binary_op (
     109        ctxt, NULL,
     110        GCC_JIT_BINARY_OP_MULT,
     111        char_type,
     112        gcc_jit_lvalue_as_rvalue (
     113  	gcc_jit_rvalue_dereference_field (
     114  	  gcc_jit_param_as_rvalue (param_f),
     115  	  NULL,
     116  	  x)),
     117        gcc_jit_lvalue_as_rvalue (
     118  	gcc_jit_rvalue_dereference_field (
     119  	gcc_jit_param_as_rvalue (param_f),
     120  	NULL,
     121  	y))));
     122  
     123    /* Build the writer fn.  */
     124    gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (struct_type);
     125    gcc_jit_param *param_g =
     126      gcc_jit_context_new_param (ctxt, NULL, ptr_type, "g");
     127    gcc_jit_function *fn_test_writing =
     128      gcc_jit_context_new_function (ctxt, NULL,
     129                                    GCC_JIT_FUNCTION_EXPORTED,
     130                                    char_type,
     131                                    writer_fn_name,
     132                                    1, &param_g,
     133                                    0);
     134  
     135    /* g->x = 5; */
     136    gcc_jit_block *writing_block = gcc_jit_function_new_block (fn_test_writing, NULL);
     137    gcc_jit_block_add_assignment (
     138      writing_block, NULL,
     139      gcc_jit_rvalue_dereference_field (gcc_jit_param_as_rvalue (param_g),
     140  				      NULL, x),
     141      gcc_jit_context_new_rvalue_from_int (ctxt, char_type, 5));
     142  
     143    /* g->y = 7; */
     144    gcc_jit_block_add_assignment (
     145      writing_block, NULL,
     146      gcc_jit_rvalue_dereference_field (gcc_jit_param_as_rvalue (param_g),
     147  				      NULL, y),
     148      gcc_jit_context_new_rvalue_from_int (ctxt, char_type, 7));
     149  
     150    /* return READER_FN_NAME (g); */
     151    gcc_jit_rvalue *arg = gcc_jit_param_as_rvalue (param_g);
     152    gcc_jit_block_end_with_return (
     153      writing_block,
     154      NULL,
     155      gcc_jit_context_new_call (
     156        ctxt, NULL,
     157        fn_test_reading,
     158        1, &arg));
     159  }
     160  
     161  /* Implement a verifier function for a given struct.  */
     162  
     163  #define IMPL_VERIFY_ALIGNED_CODE(TYPENAME) \
     164    static void								\
     165    verify_aligned_code_ ##TYPENAME (gcc_jit_context *ctxt,		\
     166  				   gcc_jit_result *result,		\
     167  				   const char *writer_fn_name)		\
     168    {									\
     169    typedef char (*fn_type) (struct TYPENAME *);				\
     170    CHECK_NON_NULL (result);						\
     171  									\
     172    struct TYPENAME tmp;							\
     173    memset (&tmp, 0xac, sizeof (tmp));					\
     174  									\
     175    fn_type test_writing =						\
     176      (fn_type)gcc_jit_result_get_code (result, writer_fn_name);		\
     177    CHECK_NON_NULL (test_writing);					\
     178  									\
     179    /* Verify that the code correctly returns the product of the fields.  */ \
     180    CHECK_VALUE (test_writing (&tmp), 35);				\
     181  									\
     182    /* Verify the we can read the values of the fields, and thus that the \
     183       struct layout agrees with that of the C frontend.  */		\
     184    CHECK_VALUE (tmp.x, 5);						\
     185    CHECK_VALUE (tmp.y, 7);						\
     186    }
     187  
     188  void
     189  create_code (gcc_jit_context *ctxt, void *user_data)
     190  {
     191    create_aligned_code (ctxt, "s2", 2, "test_aligned_reading_s2",
     192  		       "test_aligned_writing_s2");
     193    create_aligned_code (ctxt, "s4", 4, "test_aligned_reading_s4",
     194  		       "test_aligned_writing_s4");
     195    create_aligned_code (ctxt, "s8", 8, "test_aligned_reading_s8",
     196  		       "test_aligned_writing_s8");
     197    create_aligned_code (ctxt, "s16", 16, "test_aligned_reading_s16",
     198  		       "test_aligned_writing_s16");
     199    create_aligned_code (ctxt, "s32", 32, "test_aligned_reading_s32",
     200  		       "test_aligned_writing_s32");
     201    create_aligned_code (ctxt, "s64", 64, "test_aligned_reading_s64",
     202  		       "test_aligned_writing_s64");
     203    create_aligned_code (ctxt, "s128", 128, "test_aligned_reading_s128",
     204  		       "test_aligned_writing_s128");
     205  }
     206  
     207  IMPL_VERIFY_ALIGNED_CODE(s2)
     208  IMPL_VERIFY_ALIGNED_CODE(s4)
     209  IMPL_VERIFY_ALIGNED_CODE(s8)
     210  IMPL_VERIFY_ALIGNED_CODE(s16)
     211  IMPL_VERIFY_ALIGNED_CODE(s32)
     212  IMPL_VERIFY_ALIGNED_CODE(s64)
     213  IMPL_VERIFY_ALIGNED_CODE(s128)
     214  
     215  void
     216  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
     217  {
     218    verify_aligned_code_s2 (ctxt, result,
     219  			  "test_aligned_writing_s2");
     220    verify_aligned_code_s4 (ctxt, result,
     221  			  "test_aligned_writing_s4");
     222    verify_aligned_code_s8 (ctxt, result,
     223  			  "test_aligned_writing_s8");
     224    verify_aligned_code_s16 (ctxt, result,
     225  			   "test_aligned_writing_s16");
     226    verify_aligned_code_s32 (ctxt, result,
     227  			   "test_aligned_writing_s32");
     228    verify_aligned_code_s64 (ctxt, result,
     229  			   "test_aligned_writing_s64");
     230    verify_aligned_code_s128 (ctxt, result,
     231  			   "test_aligned_writing_s128");
     232  }