github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/testsuite/libffi.call/float_va.c (about)

     1  /* Area:        fp and variadics
     2     Purpose:     check fp inputs and returns work on variadics, even the fixed params
     3     Limitations: None
     4     PR:          none
     5     Originator:  <david.gilbert@linaro.org> 2011-01-25
     6  
     7     Intended to stress the difference in ABI on ARM vfp
     8  */
     9  
    10  /* { dg-do run } */
    11  
    12  #include <stdarg.h>
    13  
    14  #include "ffitest.h"
    15  
    16  /* prints out all the parameters, and returns the sum of them all.
    17   * 'x' is the number of variadic parameters all of which are double in this test
    18   */
    19  double float_va_fn(unsigned int x, double y,...)
    20  {
    21    double total=0.0;
    22    va_list ap;
    23    unsigned int i;
    24  
    25    total+=(double)x;
    26    total+=y;
    27  
    28    printf("%u: %.1f :", x, y);
    29  
    30    va_start(ap, y);
    31    for(i=0;i<x;i++)
    32    {
    33      double arg=va_arg(ap, double);
    34      total+=arg;
    35      printf(" %d:%.1f ", i, arg);
    36    }
    37    va_end(ap);
    38  
    39    printf(" total: %.1f\n", total);
    40  
    41    return total;
    42  }
    43  
    44  int main (void)
    45  {
    46    ffi_cif    cif;
    47  
    48    ffi_type    *arg_types[5];
    49    void        *values[5];
    50    double        doubles[5];
    51    unsigned int firstarg;
    52    double        resfp;
    53  
    54    /* First test, pass float_va_fn(0,2.0) - note there are no actual
    55     * variadic parameters, but it's declared variadic so the ABI may be
    56     * different. */
    57    /* Call it statically and then via ffi */
    58    resfp=float_va_fn(0,2.0);
    59    /* { dg-output "0: 2.0 : total: 2.0" } */
    60    printf("compiled: %.1f\n", resfp);
    61    /* { dg-output "\ncompiled: 2.0" } */
    62  
    63    arg_types[0] = &ffi_type_uint;
    64    arg_types[1] = &ffi_type_double;
    65    arg_types[2] = NULL;
    66    CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 2,
    67          &ffi_type_double, arg_types) == FFI_OK);
    68  
    69    firstarg = 0;
    70    doubles[0] = 2.0;
    71    values[0] = &firstarg;
    72    values[1] = &doubles[0];
    73    ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
    74    /* { dg-output "\n0: 2.0 : total: 2.0" } */
    75    printf("ffi: %.1f\n", resfp);
    76    /* { dg-output "\nffi: 2.0" } */
    77  
    78    /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
    79    /* Call it statically and then via ffi */
    80    resfp=float_va_fn(2,2.0,3.0,4.0);
    81    /* { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" } */
    82    printf("compiled: %.1f\n", resfp);
    83    /* { dg-output "\ncompiled: 11.0" } */
    84  
    85    arg_types[0] = &ffi_type_uint;
    86    arg_types[1] = &ffi_type_double;
    87    arg_types[2] = &ffi_type_double;
    88    arg_types[3] = &ffi_type_double;
    89    arg_types[4] = NULL;
    90    CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 4,
    91          &ffi_type_double, arg_types) == FFI_OK);
    92  
    93    firstarg = 2;
    94    doubles[0] = 2.0;
    95    doubles[1] = 3.0;
    96    doubles[2] = 4.0;
    97    values[0] = &firstarg;
    98    values[1] = &doubles[0];
    99    values[2] = &doubles[1];
   100    values[3] = &doubles[2];
   101    ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
   102    /* { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" } */
   103    printf("ffi: %.1f\n", resfp);
   104    /* { dg-output "\nffi: 11.0" } */
   105  
   106    exit(0);
   107  }