1bbbf1280Sopenharmony_ci/* 2bbbf1280Sopenharmony_ci * Microbenchmark for math functions. 3bbbf1280Sopenharmony_ci * 4bbbf1280Sopenharmony_ci * Copyright (c) 2018-2020, Arm Limited. 5bbbf1280Sopenharmony_ci * SPDX-License-Identifier: MIT 6bbbf1280Sopenharmony_ci */ 7bbbf1280Sopenharmony_ci 8bbbf1280Sopenharmony_ci#undef _GNU_SOURCE 9bbbf1280Sopenharmony_ci#define _GNU_SOURCE 1 10bbbf1280Sopenharmony_ci#include <stdint.h> 11bbbf1280Sopenharmony_ci#include <stdlib.h> 12bbbf1280Sopenharmony_ci#include <stdio.h> 13bbbf1280Sopenharmony_ci#include <string.h> 14bbbf1280Sopenharmony_ci#include <time.h> 15bbbf1280Sopenharmony_ci#include <math.h> 16bbbf1280Sopenharmony_ci#include "mathlib.h" 17bbbf1280Sopenharmony_ci 18bbbf1280Sopenharmony_ci#ifndef WANT_VMATH 19bbbf1280Sopenharmony_ci/* Enable the build of vector math code. */ 20bbbf1280Sopenharmony_ci# define WANT_VMATH 1 21bbbf1280Sopenharmony_ci#endif 22bbbf1280Sopenharmony_ci 23bbbf1280Sopenharmony_ci/* Number of measurements, best result is reported. */ 24bbbf1280Sopenharmony_ci#define MEASURE 60 25bbbf1280Sopenharmony_ci/* Array size. */ 26bbbf1280Sopenharmony_ci#define N 8000 27bbbf1280Sopenharmony_ci/* Iterations over the array. */ 28bbbf1280Sopenharmony_ci#define ITER 125 29bbbf1280Sopenharmony_ci 30bbbf1280Sopenharmony_cistatic double *Trace; 31bbbf1280Sopenharmony_cistatic size_t trace_size; 32bbbf1280Sopenharmony_cistatic double A[N]; 33bbbf1280Sopenharmony_cistatic float Af[N]; 34bbbf1280Sopenharmony_cistatic long measurecount = MEASURE; 35bbbf1280Sopenharmony_cistatic long itercount = ITER; 36bbbf1280Sopenharmony_ci 37bbbf1280Sopenharmony_ci#if __aarch64__ && WANT_VMATH 38bbbf1280Sopenharmony_citypedef __f64x2_t v_double; 39bbbf1280Sopenharmony_ci 40bbbf1280Sopenharmony_ci#define v_double_len() 2 41bbbf1280Sopenharmony_ci 42bbbf1280Sopenharmony_cistatic inline v_double 43bbbf1280Sopenharmony_civ_double_load (const double *p) 44bbbf1280Sopenharmony_ci{ 45bbbf1280Sopenharmony_ci return (v_double){p[0], p[1]}; 46bbbf1280Sopenharmony_ci} 47bbbf1280Sopenharmony_ci 48bbbf1280Sopenharmony_cistatic inline v_double 49bbbf1280Sopenharmony_civ_double_dup (double x) 50bbbf1280Sopenharmony_ci{ 51bbbf1280Sopenharmony_ci return (v_double){x, x}; 52bbbf1280Sopenharmony_ci} 53bbbf1280Sopenharmony_ci 54bbbf1280Sopenharmony_citypedef __f32x4_t v_float; 55bbbf1280Sopenharmony_ci 56bbbf1280Sopenharmony_ci#define v_float_len() 4 57bbbf1280Sopenharmony_ci 58bbbf1280Sopenharmony_cistatic inline v_float 59bbbf1280Sopenharmony_civ_float_load (const float *p) 60bbbf1280Sopenharmony_ci{ 61bbbf1280Sopenharmony_ci return (v_float){p[0], p[1], p[2], p[3]}; 62bbbf1280Sopenharmony_ci} 63bbbf1280Sopenharmony_ci 64bbbf1280Sopenharmony_cistatic inline v_float 65bbbf1280Sopenharmony_civ_float_dup (float x) 66bbbf1280Sopenharmony_ci{ 67bbbf1280Sopenharmony_ci return (v_float){x, x, x, x}; 68bbbf1280Sopenharmony_ci} 69bbbf1280Sopenharmony_ci#else 70bbbf1280Sopenharmony_ci/* dummy definitions to make things compile. */ 71bbbf1280Sopenharmony_citypedef double v_double; 72bbbf1280Sopenharmony_citypedef float v_float; 73bbbf1280Sopenharmony_ci#define v_double_len(x) 1 74bbbf1280Sopenharmony_ci#define v_double_load(x) (x)[0] 75bbbf1280Sopenharmony_ci#define v_double_dup(x) (x) 76bbbf1280Sopenharmony_ci#define v_float_len(x) 1 77bbbf1280Sopenharmony_ci#define v_float_load(x) (x)[0] 78bbbf1280Sopenharmony_ci#define v_float_dup(x) (x) 79bbbf1280Sopenharmony_ci#endif 80bbbf1280Sopenharmony_ci 81bbbf1280Sopenharmony_cistatic double 82bbbf1280Sopenharmony_cidummy (double x) 83bbbf1280Sopenharmony_ci{ 84bbbf1280Sopenharmony_ci return x; 85bbbf1280Sopenharmony_ci} 86bbbf1280Sopenharmony_ci 87bbbf1280Sopenharmony_cistatic float 88bbbf1280Sopenharmony_cidummyf (float x) 89bbbf1280Sopenharmony_ci{ 90bbbf1280Sopenharmony_ci return x; 91bbbf1280Sopenharmony_ci} 92bbbf1280Sopenharmony_ci 93bbbf1280Sopenharmony_ci#if WANT_VMATH 94bbbf1280Sopenharmony_ci#if __aarch64__ 95bbbf1280Sopenharmony_cistatic v_double 96bbbf1280Sopenharmony_ci__v_dummy (v_double x) 97bbbf1280Sopenharmony_ci{ 98bbbf1280Sopenharmony_ci return x; 99bbbf1280Sopenharmony_ci} 100bbbf1280Sopenharmony_ci 101bbbf1280Sopenharmony_cistatic v_float 102bbbf1280Sopenharmony_ci__v_dummyf (v_float x) 103bbbf1280Sopenharmony_ci{ 104bbbf1280Sopenharmony_ci return x; 105bbbf1280Sopenharmony_ci} 106bbbf1280Sopenharmony_ci 107bbbf1280Sopenharmony_ci#ifdef __vpcs 108bbbf1280Sopenharmony_ci__vpcs static v_double 109bbbf1280Sopenharmony_ci__vn_dummy (v_double x) 110bbbf1280Sopenharmony_ci{ 111bbbf1280Sopenharmony_ci return x; 112bbbf1280Sopenharmony_ci} 113bbbf1280Sopenharmony_ci 114bbbf1280Sopenharmony_ci__vpcs static v_float 115bbbf1280Sopenharmony_ci__vn_dummyf (v_float x) 116bbbf1280Sopenharmony_ci{ 117bbbf1280Sopenharmony_ci return x; 118bbbf1280Sopenharmony_ci} 119bbbf1280Sopenharmony_ci 120bbbf1280Sopenharmony_ci__vpcs static v_float 121bbbf1280Sopenharmony_cixy__vn_powf (v_float x) 122bbbf1280Sopenharmony_ci{ 123bbbf1280Sopenharmony_ci return __vn_powf (x, x); 124bbbf1280Sopenharmony_ci} 125bbbf1280Sopenharmony_ci 126bbbf1280Sopenharmony_ci__vpcs static v_float 127bbbf1280Sopenharmony_cixy_Z_powf (v_float x) 128bbbf1280Sopenharmony_ci{ 129bbbf1280Sopenharmony_ci return _ZGVnN4vv_powf (x, x); 130bbbf1280Sopenharmony_ci} 131bbbf1280Sopenharmony_ci 132bbbf1280Sopenharmony_ci__vpcs static v_double 133bbbf1280Sopenharmony_cixy__vn_pow (v_double x) 134bbbf1280Sopenharmony_ci{ 135bbbf1280Sopenharmony_ci return __vn_pow (x, x); 136bbbf1280Sopenharmony_ci} 137bbbf1280Sopenharmony_ci 138bbbf1280Sopenharmony_ci__vpcs static v_double 139bbbf1280Sopenharmony_cixy_Z_pow (v_double x) 140bbbf1280Sopenharmony_ci{ 141bbbf1280Sopenharmony_ci return _ZGVnN2vv_pow (x, x); 142bbbf1280Sopenharmony_ci} 143bbbf1280Sopenharmony_ci#endif 144bbbf1280Sopenharmony_ci 145bbbf1280Sopenharmony_cistatic v_float 146bbbf1280Sopenharmony_cixy__v_powf (v_float x) 147bbbf1280Sopenharmony_ci{ 148bbbf1280Sopenharmony_ci return __v_powf (x, x); 149bbbf1280Sopenharmony_ci} 150bbbf1280Sopenharmony_ci 151bbbf1280Sopenharmony_cistatic v_double 152bbbf1280Sopenharmony_cixy__v_pow (v_double x) 153bbbf1280Sopenharmony_ci{ 154bbbf1280Sopenharmony_ci return __v_pow (x, x); 155bbbf1280Sopenharmony_ci} 156bbbf1280Sopenharmony_ci#endif 157bbbf1280Sopenharmony_ci 158bbbf1280Sopenharmony_cistatic float 159bbbf1280Sopenharmony_cixy__s_powf (float x) 160bbbf1280Sopenharmony_ci{ 161bbbf1280Sopenharmony_ci return __s_powf (x, x); 162bbbf1280Sopenharmony_ci} 163bbbf1280Sopenharmony_ci 164bbbf1280Sopenharmony_cistatic double 165bbbf1280Sopenharmony_cixy__s_pow (double x) 166bbbf1280Sopenharmony_ci{ 167bbbf1280Sopenharmony_ci return __s_pow (x, x); 168bbbf1280Sopenharmony_ci} 169bbbf1280Sopenharmony_ci#endif 170bbbf1280Sopenharmony_ci 171bbbf1280Sopenharmony_cistatic double 172bbbf1280Sopenharmony_cixypow (double x) 173bbbf1280Sopenharmony_ci{ 174bbbf1280Sopenharmony_ci return pow (x, x); 175bbbf1280Sopenharmony_ci} 176bbbf1280Sopenharmony_ci 177bbbf1280Sopenharmony_cistatic float 178bbbf1280Sopenharmony_cixypowf (float x) 179bbbf1280Sopenharmony_ci{ 180bbbf1280Sopenharmony_ci return powf (x, x); 181bbbf1280Sopenharmony_ci} 182bbbf1280Sopenharmony_ci 183bbbf1280Sopenharmony_cistatic double 184bbbf1280Sopenharmony_cixpow (double x) 185bbbf1280Sopenharmony_ci{ 186bbbf1280Sopenharmony_ci return pow (x, 23.4); 187bbbf1280Sopenharmony_ci} 188bbbf1280Sopenharmony_ci 189bbbf1280Sopenharmony_cistatic float 190bbbf1280Sopenharmony_cixpowf (float x) 191bbbf1280Sopenharmony_ci{ 192bbbf1280Sopenharmony_ci return powf (x, 23.4f); 193bbbf1280Sopenharmony_ci} 194bbbf1280Sopenharmony_ci 195bbbf1280Sopenharmony_cistatic double 196bbbf1280Sopenharmony_ciypow (double x) 197bbbf1280Sopenharmony_ci{ 198bbbf1280Sopenharmony_ci return pow (2.34, x); 199bbbf1280Sopenharmony_ci} 200bbbf1280Sopenharmony_ci 201bbbf1280Sopenharmony_cistatic float 202bbbf1280Sopenharmony_ciypowf (float x) 203bbbf1280Sopenharmony_ci{ 204bbbf1280Sopenharmony_ci return powf (2.34f, x); 205bbbf1280Sopenharmony_ci} 206bbbf1280Sopenharmony_ci 207bbbf1280Sopenharmony_cistatic float 208bbbf1280Sopenharmony_cisincosf_wrap (float x) 209bbbf1280Sopenharmony_ci{ 210bbbf1280Sopenharmony_ci float s, c; 211bbbf1280Sopenharmony_ci sincosf (x, &s, &c); 212bbbf1280Sopenharmony_ci return s + c; 213bbbf1280Sopenharmony_ci} 214bbbf1280Sopenharmony_ci 215bbbf1280Sopenharmony_cistatic const struct fun 216bbbf1280Sopenharmony_ci{ 217bbbf1280Sopenharmony_ci const char *name; 218bbbf1280Sopenharmony_ci int prec; 219bbbf1280Sopenharmony_ci int vec; 220bbbf1280Sopenharmony_ci double lo; 221bbbf1280Sopenharmony_ci double hi; 222bbbf1280Sopenharmony_ci union 223bbbf1280Sopenharmony_ci { 224bbbf1280Sopenharmony_ci double (*d) (double); 225bbbf1280Sopenharmony_ci float (*f) (float); 226bbbf1280Sopenharmony_ci v_double (*vd) (v_double); 227bbbf1280Sopenharmony_ci v_float (*vf) (v_float); 228bbbf1280Sopenharmony_ci#ifdef __vpcs 229bbbf1280Sopenharmony_ci __vpcs v_double (*vnd) (v_double); 230bbbf1280Sopenharmony_ci __vpcs v_float (*vnf) (v_float); 231bbbf1280Sopenharmony_ci#endif 232bbbf1280Sopenharmony_ci } fun; 233bbbf1280Sopenharmony_ci} funtab[] = { 234bbbf1280Sopenharmony_ci#define D(func, lo, hi) {#func, 'd', 0, lo, hi, {.d = func}}, 235bbbf1280Sopenharmony_ci#define F(func, lo, hi) {#func, 'f', 0, lo, hi, {.f = func}}, 236bbbf1280Sopenharmony_ci#define VD(func, lo, hi) {#func, 'd', 'v', lo, hi, {.vd = func}}, 237bbbf1280Sopenharmony_ci#define VF(func, lo, hi) {#func, 'f', 'v', lo, hi, {.vf = func}}, 238bbbf1280Sopenharmony_ci#define VND(func, lo, hi) {#func, 'd', 'n', lo, hi, {.vnd = func}}, 239bbbf1280Sopenharmony_ci#define VNF(func, lo, hi) {#func, 'f', 'n', lo, hi, {.vnf = func}}, 240bbbf1280Sopenharmony_ciD (dummy, 1.0, 2.0) 241bbbf1280Sopenharmony_ciD (exp, -9.9, 9.9) 242bbbf1280Sopenharmony_ciD (exp, 0.5, 1.0) 243bbbf1280Sopenharmony_ciD (exp2, -9.9, 9.9) 244bbbf1280Sopenharmony_ciD (log, 0.01, 11.1) 245bbbf1280Sopenharmony_ciD (log, 0.999, 1.001) 246bbbf1280Sopenharmony_ciD (log2, 0.01, 11.1) 247bbbf1280Sopenharmony_ciD (log2, 0.999, 1.001) 248bbbf1280Sopenharmony_ci{"pow", 'd', 0, 0.01, 11.1, {.d = xypow}}, 249bbbf1280Sopenharmony_ciD (xpow, 0.01, 11.1) 250bbbf1280Sopenharmony_ciD (ypow, -9.9, 9.9) 251bbbf1280Sopenharmony_ciD (erf, -6.0, 6.0) 252bbbf1280Sopenharmony_ci 253bbbf1280Sopenharmony_ciF (dummyf, 1.0, 2.0) 254bbbf1280Sopenharmony_ciF (expf, -9.9, 9.9) 255bbbf1280Sopenharmony_ciF (exp2f, -9.9, 9.9) 256bbbf1280Sopenharmony_ciF (logf, 0.01, 11.1) 257bbbf1280Sopenharmony_ciF (log2f, 0.01, 11.1) 258bbbf1280Sopenharmony_ci{"powf", 'f', 0, 0.01, 11.1, {.f = xypowf}}, 259bbbf1280Sopenharmony_ciF (xpowf, 0.01, 11.1) 260bbbf1280Sopenharmony_ciF (ypowf, -9.9, 9.9) 261bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, 0.1, 0.7, {.f = sincosf_wrap}}, 262bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, 0.8, 3.1, {.f = sincosf_wrap}}, 263bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, -3.1, 3.1, {.f = sincosf_wrap}}, 264bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, 3.3, 33.3, {.f = sincosf_wrap}}, 265bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, 100, 1000, {.f = sincosf_wrap}}, 266bbbf1280Sopenharmony_ci{"sincosf", 'f', 0, 1e6, 1e32, {.f = sincosf_wrap}}, 267bbbf1280Sopenharmony_ciF (sinf, 0.1, 0.7) 268bbbf1280Sopenharmony_ciF (sinf, 0.8, 3.1) 269bbbf1280Sopenharmony_ciF (sinf, -3.1, 3.1) 270bbbf1280Sopenharmony_ciF (sinf, 3.3, 33.3) 271bbbf1280Sopenharmony_ciF (sinf, 100, 1000) 272bbbf1280Sopenharmony_ciF (sinf, 1e6, 1e32) 273bbbf1280Sopenharmony_ciF (cosf, 0.1, 0.7) 274bbbf1280Sopenharmony_ciF (cosf, 0.8, 3.1) 275bbbf1280Sopenharmony_ciF (cosf, -3.1, 3.1) 276bbbf1280Sopenharmony_ciF (cosf, 3.3, 33.3) 277bbbf1280Sopenharmony_ciF (cosf, 100, 1000) 278bbbf1280Sopenharmony_ciF (cosf, 1e6, 1e32) 279bbbf1280Sopenharmony_ciF (erff, -4.0, 4.0) 280bbbf1280Sopenharmony_ci#if WANT_VMATH 281bbbf1280Sopenharmony_ciD (__s_sin, -3.1, 3.1) 282bbbf1280Sopenharmony_ciD (__s_cos, -3.1, 3.1) 283bbbf1280Sopenharmony_ciD (__s_exp, -9.9, 9.9) 284bbbf1280Sopenharmony_ciD (__s_log, 0.01, 11.1) 285bbbf1280Sopenharmony_ci{"__s_pow", 'd', 0, 0.01, 11.1, {.d = xy__s_pow}}, 286bbbf1280Sopenharmony_ciF (__s_expf, -9.9, 9.9) 287bbbf1280Sopenharmony_ciF (__s_expf_1u, -9.9, 9.9) 288bbbf1280Sopenharmony_ciF (__s_exp2f, -9.9, 9.9) 289bbbf1280Sopenharmony_ciF (__s_exp2f_1u, -9.9, 9.9) 290bbbf1280Sopenharmony_ciF (__s_logf, 0.01, 11.1) 291bbbf1280Sopenharmony_ci{"__s_powf", 'f', 0, 0.01, 11.1, {.f = xy__s_powf}}, 292bbbf1280Sopenharmony_ciF (__s_sinf, -3.1, 3.1) 293bbbf1280Sopenharmony_ciF (__s_cosf, -3.1, 3.1) 294bbbf1280Sopenharmony_ci#if __aarch64__ 295bbbf1280Sopenharmony_ciVD (__v_dummy, 1.0, 2.0) 296bbbf1280Sopenharmony_ciVD (__v_sin, -3.1, 3.1) 297bbbf1280Sopenharmony_ciVD (__v_cos, -3.1, 3.1) 298bbbf1280Sopenharmony_ciVD (__v_exp, -9.9, 9.9) 299bbbf1280Sopenharmony_ciVD (__v_log, 0.01, 11.1) 300bbbf1280Sopenharmony_ci{"__v_pow", 'd', 'v', 0.01, 11.1, {.vd = xy__v_pow}}, 301bbbf1280Sopenharmony_ciVF (__v_dummyf, 1.0, 2.0) 302bbbf1280Sopenharmony_ciVF (__v_expf, -9.9, 9.9) 303bbbf1280Sopenharmony_ciVF (__v_expf_1u, -9.9, 9.9) 304bbbf1280Sopenharmony_ciVF (__v_exp2f, -9.9, 9.9) 305bbbf1280Sopenharmony_ciVF (__v_exp2f_1u, -9.9, 9.9) 306bbbf1280Sopenharmony_ciVF (__v_logf, 0.01, 11.1) 307bbbf1280Sopenharmony_ci{"__v_powf", 'f', 'v', 0.01, 11.1, {.vf = xy__v_powf}}, 308bbbf1280Sopenharmony_ciVF (__v_sinf, -3.1, 3.1) 309bbbf1280Sopenharmony_ciVF (__v_cosf, -3.1, 3.1) 310bbbf1280Sopenharmony_ci#ifdef __vpcs 311bbbf1280Sopenharmony_ciVND (__vn_dummy, 1.0, 2.0) 312bbbf1280Sopenharmony_ciVND (__vn_exp, -9.9, 9.9) 313bbbf1280Sopenharmony_ciVND (_ZGVnN2v_exp, -9.9, 9.9) 314bbbf1280Sopenharmony_ciVND (__vn_log, 0.01, 11.1) 315bbbf1280Sopenharmony_ciVND (_ZGVnN2v_log, 0.01, 11.1) 316bbbf1280Sopenharmony_ci{"__vn_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy__vn_pow}}, 317bbbf1280Sopenharmony_ci{"_ZGVnN2vv_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy_Z_pow}}, 318bbbf1280Sopenharmony_ciVND (__vn_sin, -3.1, 3.1) 319bbbf1280Sopenharmony_ciVND (_ZGVnN2v_sin, -3.1, 3.1) 320bbbf1280Sopenharmony_ciVND (__vn_cos, -3.1, 3.1) 321bbbf1280Sopenharmony_ciVND (_ZGVnN2v_cos, -3.1, 3.1) 322bbbf1280Sopenharmony_ciVNF (__vn_dummyf, 1.0, 2.0) 323bbbf1280Sopenharmony_ciVNF (__vn_expf, -9.9, 9.9) 324bbbf1280Sopenharmony_ciVNF (_ZGVnN4v_expf, -9.9, 9.9) 325bbbf1280Sopenharmony_ciVNF (__vn_expf_1u, -9.9, 9.9) 326bbbf1280Sopenharmony_ciVNF (__vn_exp2f, -9.9, 9.9) 327bbbf1280Sopenharmony_ciVNF (_ZGVnN4v_exp2f, -9.9, 9.9) 328bbbf1280Sopenharmony_ciVNF (__vn_exp2f_1u, -9.9, 9.9) 329bbbf1280Sopenharmony_ciVNF (__vn_logf, 0.01, 11.1) 330bbbf1280Sopenharmony_ciVNF (_ZGVnN4v_logf, 0.01, 11.1) 331bbbf1280Sopenharmony_ci{"__vn_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy__vn_powf}}, 332bbbf1280Sopenharmony_ci{"_ZGVnN4vv_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy_Z_powf}}, 333bbbf1280Sopenharmony_ciVNF (__vn_sinf, -3.1, 3.1) 334bbbf1280Sopenharmony_ciVNF (_ZGVnN4v_sinf, -3.1, 3.1) 335bbbf1280Sopenharmony_ciVNF (__vn_cosf, -3.1, 3.1) 336bbbf1280Sopenharmony_ciVNF (_ZGVnN4v_cosf, -3.1, 3.1) 337bbbf1280Sopenharmony_ci#endif 338bbbf1280Sopenharmony_ci#endif 339bbbf1280Sopenharmony_ci#endif 340bbbf1280Sopenharmony_ci{0}, 341bbbf1280Sopenharmony_ci#undef F 342bbbf1280Sopenharmony_ci#undef D 343bbbf1280Sopenharmony_ci#undef VF 344bbbf1280Sopenharmony_ci#undef VD 345bbbf1280Sopenharmony_ci#undef VNF 346bbbf1280Sopenharmony_ci#undef VND 347bbbf1280Sopenharmony_ci}; 348bbbf1280Sopenharmony_ci 349bbbf1280Sopenharmony_cistatic void 350bbbf1280Sopenharmony_cigen_linear (double lo, double hi) 351bbbf1280Sopenharmony_ci{ 352bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 353bbbf1280Sopenharmony_ci A[i] = (lo * (N - i) + hi * i) / N; 354bbbf1280Sopenharmony_ci} 355bbbf1280Sopenharmony_ci 356bbbf1280Sopenharmony_cistatic void 357bbbf1280Sopenharmony_cigenf_linear (double lo, double hi) 358bbbf1280Sopenharmony_ci{ 359bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 360bbbf1280Sopenharmony_ci Af[i] = (float)(lo * (N - i) + hi * i) / N; 361bbbf1280Sopenharmony_ci} 362bbbf1280Sopenharmony_ci 363bbbf1280Sopenharmony_cistatic inline double 364bbbf1280Sopenharmony_ciasdouble (uint64_t i) 365bbbf1280Sopenharmony_ci{ 366bbbf1280Sopenharmony_ci union 367bbbf1280Sopenharmony_ci { 368bbbf1280Sopenharmony_ci uint64_t i; 369bbbf1280Sopenharmony_ci double f; 370bbbf1280Sopenharmony_ci } u = {i}; 371bbbf1280Sopenharmony_ci return u.f; 372bbbf1280Sopenharmony_ci} 373bbbf1280Sopenharmony_ci 374bbbf1280Sopenharmony_cistatic uint64_t seed = 0x0123456789abcdef; 375bbbf1280Sopenharmony_ci 376bbbf1280Sopenharmony_cistatic double 377bbbf1280Sopenharmony_cifrand (double lo, double hi) 378bbbf1280Sopenharmony_ci{ 379bbbf1280Sopenharmony_ci seed = 6364136223846793005ULL * seed + 1; 380bbbf1280Sopenharmony_ci return lo + (hi - lo) * (asdouble (seed >> 12 | 0x3ffULL << 52) - 1.0); 381bbbf1280Sopenharmony_ci} 382bbbf1280Sopenharmony_ci 383bbbf1280Sopenharmony_cistatic void 384bbbf1280Sopenharmony_cigen_rand (double lo, double hi) 385bbbf1280Sopenharmony_ci{ 386bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 387bbbf1280Sopenharmony_ci A[i] = frand (lo, hi); 388bbbf1280Sopenharmony_ci} 389bbbf1280Sopenharmony_ci 390bbbf1280Sopenharmony_cistatic void 391bbbf1280Sopenharmony_cigenf_rand (double lo, double hi) 392bbbf1280Sopenharmony_ci{ 393bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 394bbbf1280Sopenharmony_ci Af[i] = (float)frand (lo, hi); 395bbbf1280Sopenharmony_ci} 396bbbf1280Sopenharmony_ci 397bbbf1280Sopenharmony_cistatic void 398bbbf1280Sopenharmony_cigen_trace (int index) 399bbbf1280Sopenharmony_ci{ 400bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 401bbbf1280Sopenharmony_ci A[i] = Trace[index + i]; 402bbbf1280Sopenharmony_ci} 403bbbf1280Sopenharmony_ci 404bbbf1280Sopenharmony_cistatic void 405bbbf1280Sopenharmony_cigenf_trace (int index) 406bbbf1280Sopenharmony_ci{ 407bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 408bbbf1280Sopenharmony_ci Af[i] = (float)Trace[index + i]; 409bbbf1280Sopenharmony_ci} 410bbbf1280Sopenharmony_ci 411bbbf1280Sopenharmony_cistatic void 412bbbf1280Sopenharmony_cirun_thruput (double f (double)) 413bbbf1280Sopenharmony_ci{ 414bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 415bbbf1280Sopenharmony_ci f (A[i]); 416bbbf1280Sopenharmony_ci} 417bbbf1280Sopenharmony_ci 418bbbf1280Sopenharmony_cistatic void 419bbbf1280Sopenharmony_cirunf_thruput (float f (float)) 420bbbf1280Sopenharmony_ci{ 421bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 422bbbf1280Sopenharmony_ci f (Af[i]); 423bbbf1280Sopenharmony_ci} 424bbbf1280Sopenharmony_ci 425bbbf1280Sopenharmony_civolatile double zero = 0; 426bbbf1280Sopenharmony_ci 427bbbf1280Sopenharmony_cistatic void 428bbbf1280Sopenharmony_cirun_latency (double f (double)) 429bbbf1280Sopenharmony_ci{ 430bbbf1280Sopenharmony_ci double z = zero; 431bbbf1280Sopenharmony_ci double prev = z; 432bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 433bbbf1280Sopenharmony_ci prev = f (A[i] + prev * z); 434bbbf1280Sopenharmony_ci} 435bbbf1280Sopenharmony_ci 436bbbf1280Sopenharmony_cistatic void 437bbbf1280Sopenharmony_cirunf_latency (float f (float)) 438bbbf1280Sopenharmony_ci{ 439bbbf1280Sopenharmony_ci float z = (float)zero; 440bbbf1280Sopenharmony_ci float prev = z; 441bbbf1280Sopenharmony_ci for (int i = 0; i < N; i++) 442bbbf1280Sopenharmony_ci prev = f (Af[i] + prev * z); 443bbbf1280Sopenharmony_ci} 444bbbf1280Sopenharmony_ci 445bbbf1280Sopenharmony_cistatic void 446bbbf1280Sopenharmony_cirun_v_thruput (v_double f (v_double)) 447bbbf1280Sopenharmony_ci{ 448bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_double_len ()) 449bbbf1280Sopenharmony_ci f (v_double_load (A+i)); 450bbbf1280Sopenharmony_ci} 451bbbf1280Sopenharmony_ci 452bbbf1280Sopenharmony_cistatic void 453bbbf1280Sopenharmony_cirunf_v_thruput (v_float f (v_float)) 454bbbf1280Sopenharmony_ci{ 455bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_float_len ()) 456bbbf1280Sopenharmony_ci f (v_float_load (Af+i)); 457bbbf1280Sopenharmony_ci} 458bbbf1280Sopenharmony_ci 459bbbf1280Sopenharmony_cistatic void 460bbbf1280Sopenharmony_cirun_v_latency (v_double f (v_double)) 461bbbf1280Sopenharmony_ci{ 462bbbf1280Sopenharmony_ci v_double z = v_double_dup (zero); 463bbbf1280Sopenharmony_ci v_double prev = z; 464bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_double_len ()) 465bbbf1280Sopenharmony_ci prev = f (v_double_load (A+i) + prev * z); 466bbbf1280Sopenharmony_ci} 467bbbf1280Sopenharmony_ci 468bbbf1280Sopenharmony_cistatic void 469bbbf1280Sopenharmony_cirunf_v_latency (v_float f (v_float)) 470bbbf1280Sopenharmony_ci{ 471bbbf1280Sopenharmony_ci v_float z = v_float_dup (zero); 472bbbf1280Sopenharmony_ci v_float prev = z; 473bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_float_len ()) 474bbbf1280Sopenharmony_ci prev = f (v_float_load (Af+i) + prev * z); 475bbbf1280Sopenharmony_ci} 476bbbf1280Sopenharmony_ci 477bbbf1280Sopenharmony_ci#ifdef __vpcs 478bbbf1280Sopenharmony_cistatic void 479bbbf1280Sopenharmony_cirun_vn_thruput (__vpcs v_double f (v_double)) 480bbbf1280Sopenharmony_ci{ 481bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_double_len ()) 482bbbf1280Sopenharmony_ci f (v_double_load (A+i)); 483bbbf1280Sopenharmony_ci} 484bbbf1280Sopenharmony_ci 485bbbf1280Sopenharmony_cistatic void 486bbbf1280Sopenharmony_cirunf_vn_thruput (__vpcs v_float f (v_float)) 487bbbf1280Sopenharmony_ci{ 488bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_float_len ()) 489bbbf1280Sopenharmony_ci f (v_float_load (Af+i)); 490bbbf1280Sopenharmony_ci} 491bbbf1280Sopenharmony_ci 492bbbf1280Sopenharmony_cistatic void 493bbbf1280Sopenharmony_cirun_vn_latency (__vpcs v_double f (v_double)) 494bbbf1280Sopenharmony_ci{ 495bbbf1280Sopenharmony_ci v_double z = v_double_dup (zero); 496bbbf1280Sopenharmony_ci v_double prev = z; 497bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_double_len ()) 498bbbf1280Sopenharmony_ci prev = f (v_double_load (A+i) + prev * z); 499bbbf1280Sopenharmony_ci} 500bbbf1280Sopenharmony_ci 501bbbf1280Sopenharmony_cistatic void 502bbbf1280Sopenharmony_cirunf_vn_latency (__vpcs v_float f (v_float)) 503bbbf1280Sopenharmony_ci{ 504bbbf1280Sopenharmony_ci v_float z = v_float_dup (zero); 505bbbf1280Sopenharmony_ci v_float prev = z; 506bbbf1280Sopenharmony_ci for (int i = 0; i < N; i += v_float_len ()) 507bbbf1280Sopenharmony_ci prev = f (v_float_load (Af+i) + prev * z); 508bbbf1280Sopenharmony_ci} 509bbbf1280Sopenharmony_ci#endif 510bbbf1280Sopenharmony_ci 511bbbf1280Sopenharmony_cistatic uint64_t 512bbbf1280Sopenharmony_citic (void) 513bbbf1280Sopenharmony_ci{ 514bbbf1280Sopenharmony_ci struct timespec ts; 515bbbf1280Sopenharmony_ci if (clock_gettime (CLOCK_REALTIME, &ts)) 516bbbf1280Sopenharmony_ci abort (); 517bbbf1280Sopenharmony_ci return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 518bbbf1280Sopenharmony_ci} 519bbbf1280Sopenharmony_ci 520bbbf1280Sopenharmony_ci#define TIMEIT(run, f) do { \ 521bbbf1280Sopenharmony_ci dt = -1; \ 522bbbf1280Sopenharmony_ci run (f); /* Warm up. */ \ 523bbbf1280Sopenharmony_ci for (int j = 0; j < measurecount; j++) \ 524bbbf1280Sopenharmony_ci { \ 525bbbf1280Sopenharmony_ci uint64_t t0 = tic (); \ 526bbbf1280Sopenharmony_ci for (int i = 0; i < itercount; i++) \ 527bbbf1280Sopenharmony_ci run (f); \ 528bbbf1280Sopenharmony_ci uint64_t t1 = tic (); \ 529bbbf1280Sopenharmony_ci if (t1 - t0 < dt) \ 530bbbf1280Sopenharmony_ci dt = t1 - t0; \ 531bbbf1280Sopenharmony_ci } \ 532bbbf1280Sopenharmony_ci} while (0) 533bbbf1280Sopenharmony_ci 534bbbf1280Sopenharmony_cistatic void 535bbbf1280Sopenharmony_cibench1 (const struct fun *f, int type, double lo, double hi) 536bbbf1280Sopenharmony_ci{ 537bbbf1280Sopenharmony_ci uint64_t dt = 0; 538bbbf1280Sopenharmony_ci uint64_t ns100; 539bbbf1280Sopenharmony_ci const char *s = type == 't' ? "rthruput" : "latency"; 540bbbf1280Sopenharmony_ci int vlen = 1; 541bbbf1280Sopenharmony_ci 542bbbf1280Sopenharmony_ci if (f->vec && f->prec == 'd') 543bbbf1280Sopenharmony_ci vlen = v_double_len(); 544bbbf1280Sopenharmony_ci else if (f->vec && f->prec == 'f') 545bbbf1280Sopenharmony_ci vlen = v_float_len(); 546bbbf1280Sopenharmony_ci 547bbbf1280Sopenharmony_ci if (f->prec == 'd' && type == 't' && f->vec == 0) 548bbbf1280Sopenharmony_ci TIMEIT (run_thruput, f->fun.d); 549bbbf1280Sopenharmony_ci else if (f->prec == 'd' && type == 'l' && f->vec == 0) 550bbbf1280Sopenharmony_ci TIMEIT (run_latency, f->fun.d); 551bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 't' && f->vec == 0) 552bbbf1280Sopenharmony_ci TIMEIT (runf_thruput, f->fun.f); 553bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 'l' && f->vec == 0) 554bbbf1280Sopenharmony_ci TIMEIT (runf_latency, f->fun.f); 555bbbf1280Sopenharmony_ci else if (f->prec == 'd' && type == 't' && f->vec == 'v') 556bbbf1280Sopenharmony_ci TIMEIT (run_v_thruput, f->fun.vd); 557bbbf1280Sopenharmony_ci else if (f->prec == 'd' && type == 'l' && f->vec == 'v') 558bbbf1280Sopenharmony_ci TIMEIT (run_v_latency, f->fun.vd); 559bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 't' && f->vec == 'v') 560bbbf1280Sopenharmony_ci TIMEIT (runf_v_thruput, f->fun.vf); 561bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 'l' && f->vec == 'v') 562bbbf1280Sopenharmony_ci TIMEIT (runf_v_latency, f->fun.vf); 563bbbf1280Sopenharmony_ci#ifdef __vpcs 564bbbf1280Sopenharmony_ci else if (f->prec == 'd' && type == 't' && f->vec == 'n') 565bbbf1280Sopenharmony_ci TIMEIT (run_vn_thruput, f->fun.vnd); 566bbbf1280Sopenharmony_ci else if (f->prec == 'd' && type == 'l' && f->vec == 'n') 567bbbf1280Sopenharmony_ci TIMEIT (run_vn_latency, f->fun.vnd); 568bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 't' && f->vec == 'n') 569bbbf1280Sopenharmony_ci TIMEIT (runf_vn_thruput, f->fun.vnf); 570bbbf1280Sopenharmony_ci else if (f->prec == 'f' && type == 'l' && f->vec == 'n') 571bbbf1280Sopenharmony_ci TIMEIT (runf_vn_latency, f->fun.vnf); 572bbbf1280Sopenharmony_ci#endif 573bbbf1280Sopenharmony_ci 574bbbf1280Sopenharmony_ci if (type == 't') 575bbbf1280Sopenharmony_ci { 576bbbf1280Sopenharmony_ci ns100 = (100 * dt + itercount * N / 2) / (itercount * N); 577bbbf1280Sopenharmony_ci printf ("%9s %8s: %4u.%02u ns/elem %10llu ns in [%g %g]\n", f->name, s, 578bbbf1280Sopenharmony_ci (unsigned) (ns100 / 100), (unsigned) (ns100 % 100), 579bbbf1280Sopenharmony_ci (unsigned long long) dt, lo, hi); 580bbbf1280Sopenharmony_ci } 581bbbf1280Sopenharmony_ci else if (type == 'l') 582bbbf1280Sopenharmony_ci { 583bbbf1280Sopenharmony_ci ns100 = (100 * dt + itercount * N / vlen / 2) / (itercount * N / vlen); 584bbbf1280Sopenharmony_ci printf ("%9s %8s: %4u.%02u ns/call %10llu ns in [%g %g]\n", f->name, s, 585bbbf1280Sopenharmony_ci (unsigned) (ns100 / 100), (unsigned) (ns100 % 100), 586bbbf1280Sopenharmony_ci (unsigned long long) dt, lo, hi); 587bbbf1280Sopenharmony_ci } 588bbbf1280Sopenharmony_ci fflush (stdout); 589bbbf1280Sopenharmony_ci} 590bbbf1280Sopenharmony_ci 591bbbf1280Sopenharmony_cistatic void 592bbbf1280Sopenharmony_cibench (const struct fun *f, double lo, double hi, int type, int gen) 593bbbf1280Sopenharmony_ci{ 594bbbf1280Sopenharmony_ci if (f->prec == 'd' && gen == 'r') 595bbbf1280Sopenharmony_ci gen_rand (lo, hi); 596bbbf1280Sopenharmony_ci else if (f->prec == 'd' && gen == 'l') 597bbbf1280Sopenharmony_ci gen_linear (lo, hi); 598bbbf1280Sopenharmony_ci else if (f->prec == 'd' && gen == 't') 599bbbf1280Sopenharmony_ci gen_trace (0); 600bbbf1280Sopenharmony_ci else if (f->prec == 'f' && gen == 'r') 601bbbf1280Sopenharmony_ci genf_rand (lo, hi); 602bbbf1280Sopenharmony_ci else if (f->prec == 'f' && gen == 'l') 603bbbf1280Sopenharmony_ci genf_linear (lo, hi); 604bbbf1280Sopenharmony_ci else if (f->prec == 'f' && gen == 't') 605bbbf1280Sopenharmony_ci genf_trace (0); 606bbbf1280Sopenharmony_ci 607bbbf1280Sopenharmony_ci if (gen == 't') 608bbbf1280Sopenharmony_ci hi = trace_size / N; 609bbbf1280Sopenharmony_ci 610bbbf1280Sopenharmony_ci if (type == 'b' || type == 't') 611bbbf1280Sopenharmony_ci bench1 (f, 't', lo, hi); 612bbbf1280Sopenharmony_ci 613bbbf1280Sopenharmony_ci if (type == 'b' || type == 'l') 614bbbf1280Sopenharmony_ci bench1 (f, 'l', lo, hi); 615bbbf1280Sopenharmony_ci 616bbbf1280Sopenharmony_ci for (int i = N; i < trace_size; i += N) 617bbbf1280Sopenharmony_ci { 618bbbf1280Sopenharmony_ci if (f->prec == 'd') 619bbbf1280Sopenharmony_ci gen_trace (i); 620bbbf1280Sopenharmony_ci else 621bbbf1280Sopenharmony_ci genf_trace (i); 622bbbf1280Sopenharmony_ci 623bbbf1280Sopenharmony_ci lo = i / N; 624bbbf1280Sopenharmony_ci if (type == 'b' || type == 't') 625bbbf1280Sopenharmony_ci bench1 (f, 't', lo, hi); 626bbbf1280Sopenharmony_ci 627bbbf1280Sopenharmony_ci if (type == 'b' || type == 'l') 628bbbf1280Sopenharmony_ci bench1 (f, 'l', lo, hi); 629bbbf1280Sopenharmony_ci } 630bbbf1280Sopenharmony_ci} 631bbbf1280Sopenharmony_ci 632bbbf1280Sopenharmony_cistatic void 633bbbf1280Sopenharmony_cireadtrace (const char *name) 634bbbf1280Sopenharmony_ci{ 635bbbf1280Sopenharmony_ci int n = 0; 636bbbf1280Sopenharmony_ci FILE *f = strcmp (name, "-") == 0 ? stdin : fopen (name, "r"); 637bbbf1280Sopenharmony_ci if (!f) 638bbbf1280Sopenharmony_ci { 639bbbf1280Sopenharmony_ci printf ("openning \"%s\" failed: %m\n", name); 640bbbf1280Sopenharmony_ci exit (1); 641bbbf1280Sopenharmony_ci } 642bbbf1280Sopenharmony_ci for (;;) 643bbbf1280Sopenharmony_ci { 644bbbf1280Sopenharmony_ci if (n >= trace_size) 645bbbf1280Sopenharmony_ci { 646bbbf1280Sopenharmony_ci trace_size += N; 647bbbf1280Sopenharmony_ci Trace = realloc (Trace, trace_size * sizeof (Trace[0])); 648bbbf1280Sopenharmony_ci if (Trace == NULL) 649bbbf1280Sopenharmony_ci { 650bbbf1280Sopenharmony_ci printf ("out of memory\n"); 651bbbf1280Sopenharmony_ci exit (1); 652bbbf1280Sopenharmony_ci } 653bbbf1280Sopenharmony_ci } 654bbbf1280Sopenharmony_ci if (fscanf (f, "%lf", Trace + n) != 1) 655bbbf1280Sopenharmony_ci break; 656bbbf1280Sopenharmony_ci n++; 657bbbf1280Sopenharmony_ci } 658bbbf1280Sopenharmony_ci if (ferror (f) || n == 0) 659bbbf1280Sopenharmony_ci { 660bbbf1280Sopenharmony_ci printf ("reading \"%s\" failed: %m\n", name); 661bbbf1280Sopenharmony_ci exit (1); 662bbbf1280Sopenharmony_ci } 663bbbf1280Sopenharmony_ci fclose (f); 664bbbf1280Sopenharmony_ci if (n % N == 0) 665bbbf1280Sopenharmony_ci trace_size = n; 666bbbf1280Sopenharmony_ci for (int i = 0; n < trace_size; n++, i++) 667bbbf1280Sopenharmony_ci Trace[n] = Trace[i]; 668bbbf1280Sopenharmony_ci} 669bbbf1280Sopenharmony_ci 670bbbf1280Sopenharmony_cistatic void 671bbbf1280Sopenharmony_ciusage (void) 672bbbf1280Sopenharmony_ci{ 673bbbf1280Sopenharmony_ci printf ("usage: ./mathbench [-g rand|linear|trace] [-t latency|thruput|both] " 674bbbf1280Sopenharmony_ci "[-i low high] [-f tracefile] [-m measurements] [-c iterations] func " 675bbbf1280Sopenharmony_ci "[func2 ..]\n"); 676bbbf1280Sopenharmony_ci printf ("func:\n"); 677bbbf1280Sopenharmony_ci printf ("%7s [run all benchmarks]\n", "all"); 678bbbf1280Sopenharmony_ci for (const struct fun *f = funtab; f->name; f++) 679bbbf1280Sopenharmony_ci printf ("%7s [low: %g high: %g]\n", f->name, f->lo, f->hi); 680bbbf1280Sopenharmony_ci exit (1); 681bbbf1280Sopenharmony_ci} 682bbbf1280Sopenharmony_ci 683bbbf1280Sopenharmony_ciint 684bbbf1280Sopenharmony_cimain (int argc, char *argv[]) 685bbbf1280Sopenharmony_ci{ 686bbbf1280Sopenharmony_ci int usergen = 0, gen = 'r', type = 'b', all = 0; 687bbbf1280Sopenharmony_ci double lo = 0, hi = 0; 688bbbf1280Sopenharmony_ci const char *tracefile = "-"; 689bbbf1280Sopenharmony_ci 690bbbf1280Sopenharmony_ci argv++; 691bbbf1280Sopenharmony_ci argc--; 692bbbf1280Sopenharmony_ci for (;;) 693bbbf1280Sopenharmony_ci { 694bbbf1280Sopenharmony_ci if (argc <= 0) 695bbbf1280Sopenharmony_ci usage (); 696bbbf1280Sopenharmony_ci if (argv[0][0] != '-') 697bbbf1280Sopenharmony_ci break; 698bbbf1280Sopenharmony_ci else if (argc >= 3 && strcmp (argv[0], "-i") == 0) 699bbbf1280Sopenharmony_ci { 700bbbf1280Sopenharmony_ci usergen = 1; 701bbbf1280Sopenharmony_ci lo = strtod (argv[1], 0); 702bbbf1280Sopenharmony_ci hi = strtod (argv[2], 0); 703bbbf1280Sopenharmony_ci argv += 3; 704bbbf1280Sopenharmony_ci argc -= 3; 705bbbf1280Sopenharmony_ci } 706bbbf1280Sopenharmony_ci else if (argc >= 2 && strcmp (argv[0], "-m") == 0) 707bbbf1280Sopenharmony_ci { 708bbbf1280Sopenharmony_ci measurecount = strtol (argv[1], 0, 0); 709bbbf1280Sopenharmony_ci argv += 2; 710bbbf1280Sopenharmony_ci argc -= 2; 711bbbf1280Sopenharmony_ci } 712bbbf1280Sopenharmony_ci else if (argc >= 2 && strcmp (argv[0], "-c") == 0) 713bbbf1280Sopenharmony_ci { 714bbbf1280Sopenharmony_ci itercount = strtol (argv[1], 0, 0); 715bbbf1280Sopenharmony_ci argv += 2; 716bbbf1280Sopenharmony_ci argc -= 2; 717bbbf1280Sopenharmony_ci } 718bbbf1280Sopenharmony_ci else if (argc >= 2 && strcmp (argv[0], "-g") == 0) 719bbbf1280Sopenharmony_ci { 720bbbf1280Sopenharmony_ci gen = argv[1][0]; 721bbbf1280Sopenharmony_ci if (strchr ("rlt", gen) == 0) 722bbbf1280Sopenharmony_ci usage (); 723bbbf1280Sopenharmony_ci argv += 2; 724bbbf1280Sopenharmony_ci argc -= 2; 725bbbf1280Sopenharmony_ci } 726bbbf1280Sopenharmony_ci else if (argc >= 2 && strcmp (argv[0], "-f") == 0) 727bbbf1280Sopenharmony_ci { 728bbbf1280Sopenharmony_ci gen = 't'; /* -f implies -g trace. */ 729bbbf1280Sopenharmony_ci tracefile = argv[1]; 730bbbf1280Sopenharmony_ci argv += 2; 731bbbf1280Sopenharmony_ci argc -= 2; 732bbbf1280Sopenharmony_ci } 733bbbf1280Sopenharmony_ci else if (argc >= 2 && strcmp (argv[0], "-t") == 0) 734bbbf1280Sopenharmony_ci { 735bbbf1280Sopenharmony_ci type = argv[1][0]; 736bbbf1280Sopenharmony_ci if (strchr ("ltb", type) == 0) 737bbbf1280Sopenharmony_ci usage (); 738bbbf1280Sopenharmony_ci argv += 2; 739bbbf1280Sopenharmony_ci argc -= 2; 740bbbf1280Sopenharmony_ci } 741bbbf1280Sopenharmony_ci else 742bbbf1280Sopenharmony_ci usage (); 743bbbf1280Sopenharmony_ci } 744bbbf1280Sopenharmony_ci if (gen == 't') 745bbbf1280Sopenharmony_ci { 746bbbf1280Sopenharmony_ci readtrace (tracefile); 747bbbf1280Sopenharmony_ci lo = hi = 0; 748bbbf1280Sopenharmony_ci usergen = 1; 749bbbf1280Sopenharmony_ci } 750bbbf1280Sopenharmony_ci while (argc > 0) 751bbbf1280Sopenharmony_ci { 752bbbf1280Sopenharmony_ci int found = 0; 753bbbf1280Sopenharmony_ci all = strcmp (argv[0], "all") == 0; 754bbbf1280Sopenharmony_ci for (const struct fun *f = funtab; f->name; f++) 755bbbf1280Sopenharmony_ci if (all || strcmp (argv[0], f->name) == 0) 756bbbf1280Sopenharmony_ci { 757bbbf1280Sopenharmony_ci found = 1; 758bbbf1280Sopenharmony_ci if (!usergen) 759bbbf1280Sopenharmony_ci { 760bbbf1280Sopenharmony_ci lo = f->lo; 761bbbf1280Sopenharmony_ci hi = f->hi; 762bbbf1280Sopenharmony_ci } 763bbbf1280Sopenharmony_ci bench (f, lo, hi, type, gen); 764bbbf1280Sopenharmony_ci if (usergen && !all) 765bbbf1280Sopenharmony_ci break; 766bbbf1280Sopenharmony_ci } 767bbbf1280Sopenharmony_ci if (!found) 768bbbf1280Sopenharmony_ci printf ("unknown function: %s\n", argv[0]); 769bbbf1280Sopenharmony_ci argv++; 770bbbf1280Sopenharmony_ci argc--; 771bbbf1280Sopenharmony_ci } 772bbbf1280Sopenharmony_ci return 0; 773bbbf1280Sopenharmony_ci} 774