1From 9c739800a8915d5f2a73c840190920e95ffa1c5c Mon Sep 17 00:00:00 2001
2From: Reini Urban <rurban@cpan.org>
3Date: Fri, 18 Feb 2022 09:46:45 +0100
4Subject: [PATCH] fix armv7 asm inline error GH #115
5
6some armv7 buildroot variants fail on asm.
7we already probe for that, so use it.
8Fixes GH #115
9
10[Retrieved from:
11https://github.com/rurban/safeclib/commit/9c739800a8915d5f2a73c840190920e95ffa1c5c]
12Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
13---
14 tests/perf_private.h | 49 +++++++++++++++++++++++++-------------------
15 1 file changed, 28 insertions(+), 21 deletions(-)
16
17diff --git a/tests/perf_private.h b/tests/perf_private.h
18index 3296cb3d..843674d3 100644
19--- a/tests/perf_private.h
20+++ b/tests/perf_private.h
21@@ -1,9 +1,9 @@
22 /*------------------------------------------------------------------
23  * perf_private.h - Internal benchmarking tools
24  *
25- * 2020  Reini Urban
26+ * 2020,2022  Reini Urban
27  *
28- * Copyright (c) 2017, 2020 Reini Urban
29+ * Copyright (c) 2017, 2020, 2022 Reini Urban
30  * All rights reserved.
31  *
32  * Permission is hereby granted, free of charge, to any person
33@@ -55,13 +55,16 @@ static inline uint64_t timer_start();
34 static inline uint64_t timer_end();
35
36 static inline clock_t rdtsc() {
37-#ifdef __x86_64__
38+#ifndef ASM_INLINE
39+#define NO_CYCLE_COUNTER
40+    return clock();
41+#elif defined __x86_64__
42     uint64_t a, d;
43-    __asm__ volatile("rdtsc" : "=a"(a), "=d"(d));
44+    ASM_INLINE volatile("rdtsc" : "=a"(a), "=d"(d));
45     return (clock_t)(a | (d << 32));
46 #elif defined(__i386__)
47     clock_t x;
48-    __asm__ volatile("rdtsc" : "=A"(x));
49+    ASM_INLINE volatile("rdtsc" : "=A"(x));
50     return x;
51 #elif defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && (SIZEOF_SIZE_T == 4)
52   // V7 is the earliest arch that has a standard cyclecount (some say 6)
53@@ -69,11 +72,11 @@ static inline clock_t rdtsc() {
54   uint32_t pmuseren;
55   uint32_t pmcntenset;
56   // Read the user mode perf monitor counter access permissions.
57-  asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren));
58+  ASM_INLINE volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren));
59   if (pmuseren & 1) {  // Allows reading perfmon counters for user mode code.
60-    asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset));
61+    ASM_INLINE volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset));
62     if (pmcntenset & 0x80000000ul) {  // Is it counting?
63-      asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
64+      ASM_INLINE volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
65       // The counter is set up to count every 64th cycle
66       return (int64_t)(pmccntr) * 64;  // Should optimize to << 6
67     }
68@@ -83,22 +86,22 @@ static inline clock_t rdtsc() {
69   uint64_t pmccntr;
70   uint64_t pmuseren = 1UL;
71   // Read the user mode perf monitor counter access permissions.
72-  //asm volatile("mrs cntv_ctl_el0,  %0" : "=r" (pmuseren));
73+  //ASM_INLINE volatile("mrs cntv_ctl_el0,  %0" : "=r" (pmuseren));
74   if (pmuseren & 1) {  // Allows reading perfmon counters for user mode code.
75-    asm volatile("mrs %0, cntvct_el0" : "=r" (pmccntr));
76+    ASM_INLINE volatile("mrs %0, cntvct_el0" : "=r" (pmccntr));
77     return (uint64_t)(pmccntr) * 64;  // Should optimize to << 6
78   }
79   return (uint64_t)rdtsc();
80 #elif defined(__powerpc64__) || defined(__ppc64__)
81     uint64_t tb;
82-    __asm__ volatile (\
83+    ASM_INLINE volatile (\
84       "mfspr %0, 268"
85       : "=r" (tb));
86     return tb;
87 #elif defined(__powerpc__) || defined(__ppc__)
88     // This returns a time-base, which is not always precisely a cycle-count.
89     uint32_t tbu, tbl, tmp;
90-    __asm__ volatile (\
91+    ASM_INLINE volatile (\
92       "0:\n"
93       "mftbu %0\n"
94       "mftbl %1\n"
95@@ -109,12 +112,12 @@ static inline clock_t rdtsc() {
96     return (((uint64_t) tbu << 32) | tbl);
97 #elif defined(__sparc__)
98     uint64_t tick;
99-    asm(".byte 0x83, 0x41, 0x00, 0x00");
100-    asm("mov   %%g1, %0" : "=r" (tick));
101+    ASM_INLINE(".byte 0x83, 0x41, 0x00, 0x00");
102+    ASM_INLINE("mov   %%g1, %0" : "=r" (tick));
103     return tick;
104 #elif defined(__ia64__)
105     uint64_t itc;
106-    asm("mov %0 = ar.itc" : "=r" (itc));
107+    ASM_INLINE("mov %0 = ar.itc" : "=r" (itc));
108     return itc;
109 #else
110 #define NO_CYCLE_COUNTER
111@@ -126,9 +129,11 @@ static inline clock_t rdtsc() {
112 // 3.2.1 The Improved Benchmarking Method
113 static inline uint64_t timer_start()
114 {
115-#if defined (__i386__) || (defined(__x86_64__) && SIZEOF_SIZE_T == 4)
116+#ifndef ASM_INLINE
117+    return (uint64_t)rdtsc();
118+#elif defined (__i386__) || (defined(__x86_64__) && SIZEOF_SIZE_T == 4)
119   uint32_t cycles_high, cycles_low;
120-  __asm__ volatile
121+  ASM_INLINE volatile
122       ("cpuid\n\t"
123        "rdtsc\n\t"
124        "mov %%edx, %0\n\t"
125@@ -137,7 +142,7 @@ static inline uint64_t timer_start()
126     return ((uint64_t)cycles_high << 32) | cycles_low;
127 #elif defined __x86_64__
128   uint32_t cycles_high, cycles_low;
129-  __asm__ volatile
130+  ASM_INLINE volatile
131       ("cpuid\n\t"
132        "rdtsc\n\t"
133        "mov %%edx, %0\n\t"
134@@ -151,9 +156,11 @@ static inline uint64_t timer_start()
135
136 static inline uint64_t timer_end()
137 {
138-#if defined (__i386__) || (defined(__x86_64__) && defined (HAVE_BIT32))
139+#ifndef ASM_INLINE
140+    return (uint64_t)rdtsc();
141+#elif defined (__i386__) || (defined(__x86_64__) && defined (HAVE_BIT32))
142   uint32_t cycles_high, cycles_low;
143-  __asm__ volatile
144+ ASM_INLINE volatile
145       ("rdtscp\n\t"
146        "mov %%edx, %0\n\t"
147        "mov %%eax, %1\n\t"
148@@ -162,7 +169,7 @@ static inline uint64_t timer_end()
149     return ((uint64_t)cycles_high << 32) | cycles_low;
150 #elif defined __x86_64__
151   uint32_t cycles_high, cycles_low;
152-  __asm__ volatile
153+  ASM_INLINE volatile
154       ("rdtscp\n\t"
155        "mov %%edx, %0\n\t"
156        "mov %%eax, %1\n\t"
157