1  /* Copyright (C) 2021-2023 Free Software Foundation, Inc.
       2     Contributed by Oracle.
       3  
       4     This file is part of GNU Binutils.
       5  
       6     This program is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3, or (at your option)
       9     any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program; if not, write to the Free Software
      18     Foundation, 51 Franklin Street - Fifth Floor, Boston,
      19     MA 02110-1301, USA.  */
      20  
      21  #include <unistd.h>
      22  #include <stdlib.h>
      23  #include <stdio.h>
      24  #include <unistd.h>
      25  #include "stopwatch.h"
      26  
      27  /* endcases - examine some wierd endcases of programming style
      28   *  test cases for inlined code, macros, #included code, ...
      29   */
      30  void inc_func (int);
      31  void inc_brace (int);
      32  void inc_body (int);
      33  void inc_entry (int);
      34  void inc_middle (int);
      35  void inc_exit (int);
      36  void macro_code (int);
      37  void ext_macro_code (int);
      38  void xinline_code (int);
      39  static void s_inline_code (int);
      40  void ext_inline_code (int);
      41  
      42  #ifndef NO_INLINE
      43  void xinline_code () __attribute__ ((always_inline));
      44  void s_inline_code () __attribute__ ((always_inline));
      45  #endif
      46  
      47  #include "inc_inline.h"
      48  
      49  int n;
      50  int x1M = 1000000;
      51  int x2M = 2000000;
      52  int x8M = 8000000;
      53  
      54  /* define a macro that burns CPU time */
      55  #define burncpu(nn) \
      56          x = 0; \
      57          for (j = 0; j < (nn * x8M); j++) { \
      58                   x = x + 1; \
      59          }
      60  
      61  int
      62  endcases (int n)
      63  {
      64    hrtime_t start = gethrtime ();
      65    hrtime_t vstart = gethrvtime ();
      66  
      67    /* Log the event */
      68    wlog ("start of endcases", NULL);
      69  
      70    if (n == 0)
      71      n = 4;
      72  
      73    long long count = 0;
      74    do
      75      {
      76        /* test inlines */
      77        xinline_code (n);
      78        s_inline_code (n);
      79        ext_inline_code (n);
      80  
      81        /* test macros */
      82        macro_code (n);
      83        ext_macro_code (n);
      84  
      85        /* test various cases of #include'd code */
      86        inc_func (n);
      87        inc_brace (n);
      88        inc_body (n);
      89        inc_entry (n);
      90        inc_middle (n);
      91        inc_exit (n);
      92        count++;
      93      }
      94    while (start + testtime * 1e9 > gethrtime ());
      95  
      96    fprintf (stderr, "   Performed %lld while-loop iterations\n", count);
      97    whrvlog (gethrtime () - start, gethrvtime () - vstart, "endcases", NULL);
      98    return 0;
      99  }
     100  
     101  /* spend time in a inline locally-defined */
     102  void
     103  xinline_code (int n)
     104  {
     105    int jmax = n * x8M;
     106    volatile long x = 0;
     107    for (int j = 0; j < jmax; j++)
     108      x = x + 1;
     109    if (x < 0.0)
     110      printf ("ERROR: inline_code(): x < 0 (x=%ld)\n", x);
     111  }
     112  
     113  /* spend time in a static inline locally-defined */
     114  static void
     115  s_inline_code (int n)
     116  {
     117    int jmax = n * x8M;
     118    volatile long x = 0;
     119    for (int j = 0; j < jmax; j++)
     120      x = x + 1;
     121    if (x < 0.0)
     122      printf ("ERROR: s_inline_code(): x < 0 (x=%ld)\n", x);
     123  }
     124  
     125  /* spend time in a macro locally-defined */
     126  void
     127  macro_code (int n)
     128  {
     129    int j;
     130    volatile long x = 0;
     131    burncpu (n);
     132    if (x < 0.0)
     133      printf ("ERROR: macro_code(): x < 0 (x=%ld)\n", x);
     134  }
     135  
     136  /* spend time in a macro externally-defined */
     137  #include "inc_macro.h"
     138  
     139  void
     140  ext_macro_code (int n)
     141  {
     142    volatile long x = 0;
     143    int j;
     144    extburncpu (n);
     145    if (x < 0.0)
     146      printf ("ERROR: ext_macro_code(): x < 0 (x=%ld)\n", x);
     147  }
     148  
     149  #include "inc_func.h"
     150  
     151  void
     152  inc_brace (int n)
     153  #include "inc_brace.h"
     154  
     155  void
     156  inc_body (int n) {
     157  #include "inc_body.h"
     158  }
     159  
     160  void
     161  inc_entry (int n)
     162  #include "inc_entry.h"
     163  {
     164    int jmax = n * x8M;
     165    volatile float x = 0.0;
     166    for (int j = 0; j < jmax; j++)
     167      x = x + 1.0;
     168    if (x < 0.0)
     169      printf ("ERROR: inc_entry(): x < 0 (x=%f)\n", x);
     170  }
     171  }
     172  
     173  void
     174  inc_middle (int n)
     175  {
     176    {
     177      int jmax = n * x8M;
     178      volatile float x = 0.0;
     179      for (int j = 0; j < jmax; j++)
     180        x = x + 1.0;
     181      if (x < 0.0)
     182        printf ("ERROR: inc_middle(): loop 1: x < 0 (x=%f)\n", x);
     183    }
     184  #include "inc_body.h"
     185    {
     186      int jmax = n * x8M;
     187      volatile float x = 0.0;
     188      for (int j = 0; j < jmax; j++)
     189        x = x + 1.0;
     190      if (x < 0.0)
     191        printf ("ERROR: inc_middle(): loop 2: x < 0 (x=%f)\n", x);
     192    }
     193  }
     194  
     195  void
     196  inc_exit (int n)
     197  {
     198    {
     199      int jmax = n * x8M;
     200      volatile float x = 0.0;
     201      for (int j = 0; j < jmax; j++)
     202        x = x + 1.0;
     203      if (x < 0.0)
     204        printf ("ERROR: inc_exit(): x < 0 (x=%f)\n", x);
     205    }
     206  
     207  #include "inc_exit.h"
     208