github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/native/test/xprintf.h (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <sys/types.h> 20 21 #ifdef LOG_LEVEL 22 #define DEBUG 23 #define LOG_TRACE(_VA_ARGS__...) do { if (LOG_LEVEL >= 0) xprintf(_VA_ARGS__ ); } while (0) 24 #define LOG_DEBUG(_VA_ARGS__...) do { if (LOG_LEVEL >= 1) xprintf(_VA_ARGS__ ); } while (0) 25 #define LOG_INFO(_VA_ARGS__...) do { if (LOG_LEVEL >= 2) xprintf(_VA_ARGS__ ); } while (0) 26 #else 27 #define LOG_TRACE(_VA_ARGS__...) ((void)0) 28 #define LOG_DEBUG(_VA_ARGS__...) ((void)0) 29 #define LOG_INFO(_VA_ARGS__...) ((void)0) 30 #endif 31 32 // Note: this code is on cross-compile, so we can't use System-specific Predefined Macros here. 33 #if USE_APPLE 34 static inline void __attribute__((naked)) write_syscall(const char *s, size_t n) 35 { 36 asm volatile( 37 "movq %rsi, %rdx" 38 "\n" 39 "movq %rdi, %rsi" 40 "\n" 41 "movq $1, %rdi" 42 "\n" 43 "movq $0x02000004, %rax" 44 "\n" 45 "syscall" 46 "\n" 47 "retq" 48 "\n"); 49 } 50 #else 51 static inline void __attribute__((naked)) write_syscall(const char *s, size_t n) 52 { 53 asm volatile( 54 "movq %rsi, %rdx" 55 "\n" 56 "movq %rdi, %rsi" 57 "\n" 58 "movq $1, %rdi" 59 "\n" 60 "movq $1, %rax" 61 "\n" 62 "syscall" 63 "\n" 64 "retq" 65 "\n"); 66 } 67 #endif 68 69 static inline void printch(const char ch) 70 { 71 write_syscall(&ch, 1); 72 } 73 74 static inline void printstr(const char *s) 75 { 76 size_t n = 0; 77 const char *p = s; 78 while (*p++) 79 n++; 80 write_syscall(s, n); 81 } 82 83 static inline void printint(int64_t v) 84 { 85 char neg = 0; 86 char buf[32] = {}; 87 char *p = &buf[31]; 88 uint64_t u; 89 if (v < 0) { 90 u = ~v + 1; 91 neg = 1; 92 } else { 93 u = v; 94 } 95 if (u == 0) { 96 *--p = '0'; 97 goto sig; 98 } 99 while (u) 100 { 101 *--p = (u % 10) + '0'; 102 u /= 10; 103 } 104 sig: 105 if (neg) { 106 *--p = '-'; 107 } 108 printstr(p); 109 } 110 111 static inline void printuint(uint64_t v) 112 { 113 char buf[32] = {}; 114 char *p = &buf[31]; 115 if (v == 0) 116 { 117 printch('0'); 118 return; 119 } 120 while (v) 121 { 122 *--p = (v % 10) + '0'; 123 v /= 10; 124 } 125 printstr(p); 126 } 127 128 static const char tab[] = "0123456789abcdef"; 129 130 static inline void printhex(uintptr_t v) 131 { 132 if (v == 0) 133 { 134 printch('0'); 135 return; 136 } 137 char buf[32] = {}; 138 char *p = &buf[31]; 139 140 while (v) 141 { 142 *--p = tab[v & 0x0f]; 143 v >>= 4; 144 } 145 printstr(p); 146 } 147 148 #define MAX_BUF_LEN 1000 149 150 static inline void printbytes(GoSlice *s) 151 { 152 printch('['); 153 int i = 0; 154 if (s->len > MAX_BUF_LEN) 155 { 156 i = s->len - MAX_BUF_LEN; 157 } 158 for (; i < s->len; i++) 159 { 160 char* bytes = (char*)(s->buf); 161 printch(tab[(bytes[i] & 0xf0) >> 4]); 162 printch(tab[bytes[i] & 0x0f]); 163 if (i != s->len - 1) 164 printch(','); 165 } 166 printch(']'); 167 } 168 169 static inline void printgostr(GoString *s) 170 { 171 printch('"'); 172 if (s->len < MAX_BUF_LEN) 173 { 174 write_syscall(s->buf, s->len); 175 } 176 else 177 { 178 write_syscall(s->buf, MAX_BUF_LEN); 179 } 180 printch('"'); 181 } 182 183 static inline void do_xprintf(const char *fmt, ...) 184 { 185 __builtin_va_list va; 186 char buf[256] = {}; 187 char *p = buf; 188 __builtin_va_start(va, fmt); 189 for (;;) 190 { 191 if (*fmt == 0) 192 { 193 break; 194 } 195 if (*fmt != '%') 196 { 197 *p++ = *fmt++; 198 continue; 199 } 200 *p = 0; 201 p = buf; 202 fmt++; 203 printstr(buf); 204 switch (*fmt++) 205 { 206 case '%': 207 { 208 printch('%'); 209 break; 210 } 211 case 'g': 212 { 213 printgostr(__builtin_va_arg(va, GoString *)); 214 break; 215 } 216 case 's': 217 { 218 printstr(__builtin_va_arg(va, const char *)); 219 break; 220 } 221 case 'd': 222 { 223 printint(__builtin_va_arg(va, int64_t)); 224 break; 225 } 226 case 'u': 227 { 228 printuint(__builtin_va_arg(va, uint64_t)); 229 break; 230 } 231 case 'f': 232 { 233 printint(__builtin_va_arg(va, double)); 234 break; 235 } 236 case 'c': 237 { 238 printch((char)(__builtin_va_arg(va, int))); 239 break; 240 } 241 case 'x': 242 { 243 printhex(__builtin_va_arg(va, uintptr_t)); 244 break; 245 } 246 case 'l': 247 { 248 printbytes(__builtin_va_arg(va, GoSlice *)); 249 break; 250 } 251 } 252 } 253 __builtin_va_end(va); 254 if (p != buf) 255 { 256 *p = 0; 257 printstr(buf); 258 } 259 } 260 261 #ifdef DEBUG 262 #define xprintf(_VA_ARGS__...) do_xprintf(_VA_ARGS__) 263 #else 264 #define xprintf(_VA_ARGS__...) ((void)0) 265 #endif 266 267 static always_inline void print_longhex(const void *input, const char* s, int bytes) { 268 const uint8_t* p = (const uint8_t*)(input); 269 xprintf("%s : ", s); 270 for (int i = 0; i < bytes; i++) { 271 uintptr_t u = p[i]; 272 if (u < 0x10) xprintf("0"); 273 xprintf("%x", u); 274 if ((i + 1) < bytes && (i + 1) % 4 == 0) { 275 xprintf("-"); 276 } 277 } 278 xprintf("\n"); 279 } 280 281 #define psimd(simd) print_longhex((const void *)(simd), #simd, sizeof(*simd))