...

Text file src/github.com/bytedance/sonic/native/test/xprintf.h

Documentation: github.com/bytedance/sonic/native/test

     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
    34static 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
    51static 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
    69static inline void printch(const char ch)
    70{
    71    write_syscall(&ch, 1);
    72}
    73
    74static 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
    83static 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    }
   104sig:
   105    if (neg) {
   106        *--p = '-';
   107    }
   108    printstr(p);
   109}
   110
   111static 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
   128static const char tab[] = "0123456789abcdef";
   129
   130static 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
   150static 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
   169static 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
   183static 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
   267static 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))

View as plain text