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