nmsis_bench.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. * Copyright (c) 2019 Nuclei Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef __NMSIS_BENCH__
  19. #define __NMSIS_BENCH__
  20. /*!
  21. * @file nmsis_bench.h
  22. * @brief benchmark and helper related API for Nuclei N/NX Core
  23. */
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. #include "core_feature_base.h"
  28. #include <stdio.h>
  29. #ifdef BENCH_XLEN_MODE
  30. typedef unsigned long Bench_Type;
  31. #else
  32. #if defined(CPU_SERIES) && CPU_SERIES == 100
  33. typedef uint32_t Bench_Type;
  34. #else
  35. typedef uint64_t Bench_Type;
  36. #endif
  37. #endif
  38. /**
  39. * \defgroup NMSIS_Core_Bench_Helpers NMSIS Bench and Test Related Helper Functions
  40. * \ingroup NMSIS_Core
  41. * \brief Functions that used to do benchmark and test suite.
  42. * \details
  43. *
  44. * NMSIS benchmark and test related helper functions are provided to help do benchmark
  45. * and test case pass/fail assertion.
  46. *
  47. * If you want to do calculate cpu cycle cost of a process, you can use BENCH_xxx macros
  48. * defined in this.
  49. *
  50. * In a single c source code file, you should include `nmsis_bench.h`, and then you should place `BENCH_DECLARE_VAR();`
  51. * before call other BENCH_xxx macros. If you want to start to do benchmark, you should only call `BENCH_INIT();`
  52. * once in your source code, and then place `BENCH_START(proc_name);` and `BENCH_END(proc_name)` before
  53. * and after the process you want to measure. You can refer to `<nuclei-sdk>/application/baremetal/demo_dsp`
  54. * for how to use it.
  55. *
  56. * If you want to disable the benchmark calculation, you can place `#define DISABLE_NMSIS_BENCH`
  57. * before include `nmsis_bench.h`
  58. *
  59. * If in your c test source code, you can add `NMSIS_TEST_PASS();` and `NMSIS_TEST_FAIL();` to mark c test
  60. * is pass or fail.
  61. *
  62. * @{
  63. */
  64. /**
  65. * \brief Prepare benchmark environment
  66. * \details
  67. * Prepare benchmark required environment, such as turn on necessary units
  68. * like vpu, cycle, instret counters, hpm counters
  69. */
  70. __STATIC_FORCEINLINE void __prepare_bench_env(void)
  71. {
  72. #ifdef __riscv_vector
  73. __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS);
  74. #endif
  75. __enable_all_counter();
  76. }
  77. #ifndef READ_CYCLE
  78. /**
  79. * When XLEN=32, reading the full 64-bit CYCLE register incurs additional overhead.
  80. * `BENCH_XLEN_MODE` skips reading the upper 32 bits, reducing the extra cycle cost
  81. * and allowing for more accurate measurements of small cycle counts.
  82. *
  83. * NOTE: It is only applicable when the total cycle count does not exceed 2^32.
  84. *
  85. */
  86. #ifdef BENCH_XLEN_MODE
  87. /** Read single CYCLE register */
  88. #define READ_CYCLE __read_cycle_csr
  89. #else
  90. /** Read the whole 64 bits value of MCYCLE register */
  91. #define READ_CYCLE __get_rv_cycle
  92. #endif /* #ifdef BENCH_XLEN_MODE */
  93. #endif /* #ifndef READ_CYCLE */
  94. #ifndef DISABLE_NMSIS_BENCH
  95. /** Declare benchmark required variables, need to be placed above all BENCH_xxx macros in each c source code if BENCH_xxx used */
  96. #define BENCH_DECLARE_VAR() static volatile Bench_Type _bc_sttcyc, _bc_endcyc, _bc_usecyc, _bc_sumcyc; \
  97. static volatile unsigned long _bc_lpcnt, _bc_ercd;
  98. /** Initialize benchmark environment, need to called in before other BENCH_xxx macros are called */
  99. #define BENCH_INIT() printf("Benchmark initialized\n"); \
  100. __prepare_bench_env(); \
  101. _bc_ercd = 0; _bc_sumcyc = 0;
  102. /** Reset benchmark sum cycle and use cycle for proc */
  103. #define BENCH_RESET(proc) _bc_sumcyc = 0; _bc_usecyc = 0; _bc_lpcnt = 0; _bc_ercd = 0;
  104. /** Start to do benchmark for proc, and record start cycle, and reset error code */
  105. #define BENCH_START(proc) _bc_ercd = 0; \
  106. _bc_sttcyc = READ_CYCLE();
  107. /** Sample a benchmark for proc, and record this start -> sample cost cycle, and accumulate it to sum cycle */
  108. #define BENCH_SAMPLE(proc) _bc_endcyc = READ_CYCLE(); \
  109. _bc_usecyc = _bc_endcyc - _bc_sttcyc; \
  110. _bc_sumcyc += _bc_usecyc; _bc_lpcnt += 1;
  111. /** Mark end of benchmark for proc, and calc used cycle, and print it */
  112. #define BENCH_END(proc) BENCH_SAMPLE(proc); \
  113. printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_usecyc);
  114. /** Mark stop of benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */
  115. #define BENCH_STOP(proc) printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_sumcyc);
  116. /** Show statistics of benchmark, format: STAT, proc, loopcnt, sumcyc */
  117. #define BENCH_STAT(proc) printf("STAT, %s, %lu, %lu\n", #proc, (unsigned long)_bc_lpcnt, (unsigned long)_bc_sumcyc);
  118. /** Get benchmark use cycle */
  119. #define BENCH_GET_USECYC() (_bc_usecyc)
  120. /** Get benchmark sum cycle */
  121. #define BENCH_GET_SUMCYC() (_bc_sumcyc)
  122. /** Get benchmark loop count */
  123. #define BENCH_GET_LPCNT() (_bc_lpcnt)
  124. /** Mark benchmark for proc is errored */
  125. #define BENCH_ERROR(proc) _bc_ercd = 1;
  126. /** Show the status of the benchmark */
  127. #define BENCH_STATUS(proc) if (_bc_ercd) { \
  128. printf("ERROR, %s\n", #proc); \
  129. } else { \
  130. printf("SUCCESS, %s\n", #proc); \
  131. }
  132. #else
  133. #define BENCH_DECLARE_VAR() static volatile unsigned long _bc_ercd, _bc_lpcnt;
  134. #define BENCH_INIT() _bc_ercd = 0; __prepare_bench_env();
  135. #define BENCH_RESET(proc)
  136. #define BENCH_START(proc) _bc_ercd = 0;
  137. #define BENCH_SAMPLE(proc) _bc_lpcnt += 1;
  138. #define BENCH_END(proc)
  139. #define BENCH_STOP(proc)
  140. #define BENCH_STAT(proc)
  141. #define BENCH_GET_USECYC() (0)
  142. #define BENCH_GET_SUMCYC() (0)
  143. #define BENCH_GET_LPCNT() (_bc_lpcnt)
  144. #define BENCH_ERROR(proc) _bc_ercd = 1;
  145. #define BENCH_STATUS(proc) if (_bc_ercd) { \
  146. printf("ERROR, %s\n", #proc); \
  147. } else { \
  148. printf("SUCCESS, %s\n", #proc); \
  149. }
  150. #endif
  151. // High performance monitor bench helpers
  152. #if defined(__HPM_PRESENT) && (__HPM_PRESENT == 1) && (!defined(DISABLE_NMSIS_HPM))
  153. /* Events type select */
  154. #define EVENT_SEL_INSTRUCTION_COMMIT 0
  155. #define EVENT_SEL_MEMORY_ACCESS 1
  156. #define EVENT_SEL_TYPE_0 0
  157. #define EVENT_SEL_TYPE_1 1
  158. /* The following event type 2 and 3 are introduced in PMU v2 */
  159. #define EVENT_SEL_TYPE_2 2
  160. #define EVENT_SEL_TYPE_3 3
  161. /* Instruction commit events idx macros */
  162. #define EVENT_INSTRUCTION_COMMIT_CYCLE_COUNT 1
  163. #define EVENT_INSTRUCTION_COMMIT_RETIRED_COUNT 2
  164. /* Integer load instruction (includes LR) */
  165. #define EVENT_INSTRUCTION_COMMIT_INTEGER_LOAD 3
  166. /* Integer store instruction (includes SC) */
  167. #define EVENT_INSTRUCTION_COMMIT_INTEGER_STORE 4
  168. /* Atomic memory operation (do not include LR and SC) */
  169. #define EVENT_INSTRUCTION_COMMIT_ATOMIC_MEMORY_OPERATION 5
  170. /* System instruction */
  171. #define EVENT_INSTRUCTION_COMMIT_SYSTEM 6
  172. /* Integer computational instruction (excluding multiplication/division/remainder) */
  173. #define EVENT_INSTRUCTION_COMMIT_INTEGER_COMPUTATIONAL 7
  174. #define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH 8
  175. #define EVENT_INSTRUCTION_COMMIT_TAKEN_CONDITIONAL_BRANCH 9
  176. #define EVENT_INSTRUCTION_COMMIT_JAL 10
  177. #define EVENT_INSTRUCTION_COMMIT_JALR 11
  178. #define EVENT_INSTRUCTION_COMMIT_RETURN 12
  179. /* Control transfer instruction (CBR+JAL+JALR) */
  180. #define EVENT_INSTRUCTION_COMMIT_CONTROL_TRANSFER 13
  181. /* 14 fence instruction(Not include fence.i) */
  182. #define EVENT_INSTRUCTION_COMMIT_FENCE_INSTRUCTION 14
  183. #define EVENT_INSTRUCTION_COMMIT_INTEGER_MULTIPLICATION 15
  184. /* Integer division/remainder instruction */
  185. #define EVENT_INSTRUCTION_COMMIT_INTEGER_DIVISION_REMAINDER 16
  186. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_LOAD 17
  187. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_STORE 18
  188. /* Floating-point addition/subtraction */
  189. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_ADDITION_SUBTRACTION 19
  190. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_MULTIPLICATION 20
  191. /* Floating-point fused multiply-add (FMADD, FMSUB, FNMSUB, FNMADD) */
  192. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_FUSED_MULTIPLY_ADD_SUB 21
  193. #define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_DIVISION_OR_SQUARE_ROOT 22
  194. #define EVENT_INSTRUCTION_COMMIT_OTHER_FLOATING_POINT_INSTRUCTION 23
  195. #define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH_PREDICTION_FAIL 24
  196. /* JAL_PREDICTION_FAIL never existed, it is wrong documented, JALR_PREDICTION_FAIL should be 25 not 26 */
  197. #define EVENT_INSTRUCTION_COMMIT_JALR_PREDICTION_FAIL 25
  198. #define EVENT_INSTRUCTION_COMMIT_POP_PREDICTION_FAIL 26
  199. #define EVENT_INSTRUCTION_COMMIT_FENCEI_INSTRUCTION 27
  200. #define EVENT_INSTRUCTION_COMMIT_SFENCE_INSTRUCTION 28
  201. #define EVENT_INSTRUCTION_COMMIT_ECALL_INSTRUCTION 29
  202. #define EVENT_INSTRUCTION_COMMIT_EXCEPTION_INSTRUCTION 30
  203. #define EVENT_INSTRUCTION_COMMIT_INTERRUPT_INSTRUCTION 31
  204. /* Memory access events idx macros */
  205. #define EVENT_MEMORY_ACCESS_ICACHE_MISS 1
  206. #define EVENT_MEMORY_ACCESS_DCACHE_MISS 2
  207. #define EVENT_MEMORY_ACCESS_ITLB_MISS 3
  208. #define EVENT_MEMORY_ACCESS_DTLB_MISS 4
  209. #define EVENT_MEMORY_ACCESS_MAIN_DTLB_MISS 5
  210. #define EVENT_MEMORY_ACCESS_MAIN_TLB_MISS 5
  211. /* The following events are introduced in PMU v2 */
  212. #define EVENT_MEMORY_ACCESS_L2_CACHE_ACCESS 8
  213. #define EVENT_MEMORY_ACCESS_L2_CACHE_MISS 9
  214. /* For Single Core, the Core memory bus read/write request count
  215. * For SMP Core, the cluster memory bus read/write/prefetch request count
  216. * is initiated by current Core */
  217. #define EVENT_MEMORY_ACCESS_MEMORY_BUS_REQUEST 10
  218. #define EVENT_MEMORY_ACCESS_IFU_STALL_CYCLE 11
  219. #define EVENT_MEMORY_ACCESS_EXU_STALL_CYCLE 12
  220. #define EVENT_MEMORY_ACCESS_TIMER 13
  221. /*
  222. * Here are new event types macro naming for PMU v1 and v2.
  223. * Since the event type can be no longer summary into a group naming,
  224. * so we just use the event type id such as TYPE_0, TYPE_1, TYPE_2, TYPE_3
  225. */
  226. /* Events Type 0 (event sel == 0) event name macros */
  227. #define EVENT_TYPE_0_CYCLE_COUNT 1
  228. #define EVENT_TYPE_0_RETIRED_COUNT 2
  229. #define EVENT_TYPE_0_INTEGER_LOAD 3
  230. #define EVENT_TYPE_0_INTEGER_STORE 4
  231. #define EVENT_TYPE_0_ATOMIC_MEMORY_OPERATION 5
  232. #define EVENT_TYPE_0_SYSTEM 6
  233. #define EVENT_TYPE_0_INTEGER_COMPUTATIONAL 7
  234. #define EVENT_TYPE_0_CONDITIONAL_BRANCH 8
  235. #define EVENT_TYPE_0_TAKEN_CONDITIONAL_BRANCH 9
  236. #define EVENT_TYPE_0_JAL 10
  237. #define EVENT_TYPE_0_JALR 11
  238. #define EVENT_TYPE_0_RETURN 12
  239. #define EVENT_TYPE_0_CONTROL_TRANSFER 13
  240. #define EVENT_TYPE_0_FENCE_INSTRUCTION 14
  241. #define EVENT_TYPE_0_INTEGER_MULTIPLICATION 15
  242. #define EVENT_TYPE_0_INTEGER_DIVISION_REMAINDER 16
  243. #define EVENT_TYPE_0_FLOATING_POINT_LOAD 17
  244. #define EVENT_TYPE_0_FLOATING_POINT_STORE 18
  245. #define EVENT_TYPE_0_FLOATING_POINT_ADDITION_SUBTRACTION 19
  246. #define EVENT_TYPE_0_FLOATING_POINT_MULTIPLICATION 20
  247. #define EVENT_TYPE_0_FLOATING_POINT_FUSED_MULTIPLY_ADD_SUB 21
  248. #define EVENT_TYPE_0_FLOATING_POINT_DIVISION_OR_SQUARE_ROOT 22
  249. #define EVENT_TYPE_0_OTHER_FLOATING_POINT_INSTRUCTION 23
  250. #define EVENT_TYPE_0_CONDITIONAL_BRANCH_PREDICTION_FAIL 24
  251. #define EVENT_TYPE_0_JALR_PREDICTION_FAIL 25
  252. #define EVENT_TYPE_0_POP_PREDICTION_FAIL 26
  253. #define EVENT_TYPE_0_FENCEI_INSTRUCTION 27
  254. #define EVENT_TYPE_0_SFENCE_INSTRUCTION 28
  255. #define EVENT_TYPE_0_ECALL_INSTRUCTION 29
  256. #define EVENT_TYPE_0_EXCEPTION_INSTRUCTION 30
  257. #define EVENT_TYPE_0_INTERRUPT_INSTRUCTION 31
  258. /* Events Type 1 (event sel == 1) event name macros */
  259. #define EVENT_TYPE_1_ICACHE_READ_MISS 1
  260. #define EVENT_TYPE_1_DCACHE_RW_MISS 2
  261. #define EVENT_TYPE_1_ITLB_READ_MISS 3
  262. #define EVENT_TYPE_1_DTLB_RW_MISS 4
  263. #define EVENT_TYPE_1_MAIN_TLB_MISS 5
  264. #define EVENT_TYPE_1_L2_CACHE_ACCESS 8
  265. #define EVENT_TYPE_1_L2_CACHE_MISS 9
  266. #define EVENT_TYPE_1_MEMORY_BUS_REQUEST 10
  267. #define EVENT_TYPE_1_IFU_STALL_CYCLE 11
  268. #define EVENT_TYPE_1_EXU_STALL_CYCLE 12
  269. #define EVENT_TYPE_1_TIMER 13
  270. /* Events Type 2 (event sel == 2) event name macros */
  271. #define EVENT_TYPE_2_BRANCH_INSTRUCTION_COMMIT 2
  272. #define EVENT_TYPE_2_BRANCH_PREDICT_FAIL_COMMIT 3
  273. /* Events Type 3 (event sel == 3) event name macros */
  274. #define EVENT_TYPE_3_DCACHE_READ 0
  275. #define EVENT_TYPE_3_DCACHE_READ_MISS 1
  276. #define EVENT_TYPE_3_DCACHE_WRITE 2
  277. #define EVENT_TYPE_3_DCACHE_WRITE_MISS 3
  278. #define EVENT_TYPE_3_DCACHE_PREFETCH 4
  279. #define EVENT_TYPE_3_DCACHE_PREFETCH_MISS 5
  280. #define EVENT_TYPE_3_ICACHE_READ 6
  281. #define EVENT_TYPE_3_ICACHE_PREFETCH 8
  282. #define EVENT_TYPE_3_ICACHE_PREFETCH_MISS 9
  283. #define EVENT_TYPE_3_L2_CACHE_READ 10
  284. #define EVENT_TYPE_3_L2_CACHE_READ_MISS 11
  285. #define EVENT_TYPE_3_L2_CACHE_WRITE 12
  286. #define EVENT_TYPE_3_L2_CACHE_WRITE_MISS 13
  287. #define EVENT_TYPE_3_L2_CACHE_PREFETCH_HIT 14
  288. #define EVENT_TYPE_3_L2_CACHE_PREFETCH_MISS 15
  289. #define EVENT_TYPE_3_DTLB_READ 16
  290. #define EVENT_TYPE_3_DTLB_READ_MISS 17
  291. #define EVENT_TYPE_3_DTLB_WRITE 18
  292. #define EVENT_TYPE_3_DTLB_WRITE_MISS 19
  293. #define EVENT_TYPE_3_ITLB_READ 20
  294. #define EVENT_TYPE_3_BTB_READ 22
  295. #define EVENT_TYPE_3_BTB_READ_MISS 23
  296. #define EVENT_TYPE_3_BTB_WRITE 24
  297. #define EVENT_TYPE_3_BTB_WRITE_MISS 25
  298. /* Enable the corresponding performance monitor counter increment for events in Machine/Supervisor/User Mode */
  299. #define MSU_EVENT_ENABLE 0x0F
  300. #define MEVENT_EN 0x08
  301. #define SEVENT_EN 0x02
  302. #define UEVENT_EN 0x01
  303. #ifdef BENCH_XLEN_MODE
  304. /**
  305. * NOTE: when XLEN=32 and `BENCH_XLEN_MODE` is enabled, the counter should not exceed 2^32
  306. */
  307. #define READ_HPM_COUNTER __read_hpm_counter
  308. #else
  309. #define READ_HPM_COUNTER __get_hpm_counter
  310. #endif /* #ifdef BENCH_XLEN_MODE */
  311. /** Declare high performance monitor counter idx benchmark required variables, need to be placed above all HPM_xxx macros in each c source code if HPM_xxx used */
  312. #define HPM_DECLARE_VAR(idx) static volatile Bench_Type __hpm_sttcyc##idx, __hpm_endcyc##idx, __hpm_usecyc##idx, __hpm_sumcyc##idx; \
  313. static volatile unsigned long __hpm_lpcnt##idx, __hpm_val##idx;
  314. #define HPM_SEL_ENABLE(ena) (ena << 28)
  315. #define HPM_SEL_EVENT(sel, idx) ((sel) | (idx << 4))
  316. /** Construct a event variable to be set(sel -> event_sel, idx -> event_idx, ena -> m/s/u_enable) */
  317. #define HPM_EVENT(sel, idx, ena) (HPM_SEL_ENABLE(ena) | HPM_SEL_EVENT(sel, idx))
  318. /** Initialize high performance monitor environment, need to called in before other HPM_xxx macros are called */
  319. #define HPM_INIT() printf("High performance monitor initialized\n"); \
  320. __prepare_bench_env();
  321. /** Reset high performance benchmark for proc using counter which index is idx */
  322. #define HPM_RESET(idx, proc, event) __hpm_sumcyc##idx = 0; __hpm_lpcnt##idx = 0;
  323. /** Start to do high performance benchmark for proc, and record start hpm counter */
  324. #define HPM_START(idx, proc, event) \
  325. __hpm_val##idx = (event); \
  326. __set_hpm_event(idx, __hpm_val##idx); \
  327. __set_hpm_counter(idx, 0); \
  328. __hpm_sttcyc##idx = READ_HPM_COUNTER(idx);
  329. /** Do high performance benchmark sample for proc, and sum it into sum counter */
  330. #define HPM_SAMPLE(idx, proc, event) \
  331. __hpm_endcyc##idx = READ_HPM_COUNTER(idx); \
  332. __hpm_usecyc##idx = __hpm_endcyc##idx - __hpm_sttcyc##idx; \
  333. __hpm_sumcyc##idx += __hpm_usecyc##idx; \
  334. __hpm_lpcnt##idx += 1;
  335. /** Mark end of high performance benchmark for proc, and calc used hpm counter value */
  336. #define HPM_END(idx, proc, event) \
  337. HPM_SAMPLE(idx, proc, event); \
  338. printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_usecyc##idx);
  339. /** Mark stop of hpm benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */
  340. #define HPM_STOP(idx, proc, event) \
  341. printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_sumcyc##idx);
  342. /** Show statistics of hpm benchmark, format: STATHPM#idx:event, proc, loopcnt, sumcyc */
  343. #define HPM_STAT(idx, proc, event) \
  344. printf("STATHPM%d:0x%x, %s, %lu, %lu\n", idx, event, #proc, (unsigned long)__hpm_lpcnt##idx, (unsigned long)__hpm_sumcyc##idx);
  345. /** Get hpm benchmark use cycle for counter idx */
  346. #define HPM_GET_USECYC(idx) (__hpm_usecyc##idx)
  347. /** Get hpm benchmark sum cycle for counter idx */
  348. #define HPM_GET_SUMCYC(idx) (__hpm_sumcyc##idx)
  349. /** Get hpm benchmark loop count for counter idx */
  350. #define HPM_GET_LPCNT(idx) (__hpm_lpcnt##idx)
  351. #else
  352. #define HPM_DECLARE_VAR(idx)
  353. #define HPM_EVENT(sel, idx, ena)
  354. #define HPM_INIT()
  355. #define HPM_RESET(idx, proc, event)
  356. #define HPM_START(idx, proc, event)
  357. #define HPM_SAMPLE(idx, proc, event)
  358. #define HPM_END(idx, proc, event)
  359. #define HPM_STOP(idx, proc, event)
  360. #define HPM_STAT(idx, proc, event)
  361. #define HPM_GET_USECYC(idx) (0)
  362. #define HPM_GET_SUMCYC(idx) (0)
  363. #define HPM_GET_LPCNT(idx) (1)
  364. #endif
  365. // NMSIS Helpers
  366. #ifndef DISABLE_NMSIS_HELPER
  367. /** Mark test or application passed */
  368. #define NMSIS_TEST_PASS() printf("\nNMSIS_TEST_PASS\n");
  369. /** Mark test or application failed */
  370. #define NMSIS_TEST_FAIL() printf("\nNMSIS_TEST_FAIL\n");
  371. #else
  372. #define NMSIS_TEST_PASS()
  373. #define NMSIS_TEST_FAIL()
  374. #endif
  375. /** @} */ /* End of Doxygen Group NMSIS_Core_Bench_Helpers */
  376. #ifdef __cplusplus
  377. }
  378. #endif
  379. #endif /* __NMSIS_BENCH__ */