2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00
sonic/native/test/xprintf.h
liu 2dc405d750
opt: faster skip in ast (#345)
* opt: faster skip in ast

* ci: remove excited repo
2023-01-09 16:20:36 +08:00

233 lines
No EOL
4.3 KiB
C

/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef XPRINTF_H
#define XPRINTF_H
#include <sys/types.h>
static inline void __attribute__((naked)) write_syscall(const char *s, size_t n)
{
asm volatile(
"movq %rsi, %rdx"
"\n"
"movq %rdi, %rsi"
"\n"
"movq $1, %rdi"
"\n"
"movq $0x02000004, %rax"
"\n"
"syscall"
"\n"
"retq"
"\n");
}
static inline void printch(const char ch)
{
write_syscall(&ch, 1);
}
static inline void printstr(const char *s)
{
size_t n = 0;
const char *p = s;
while (*p++)
n++;
write_syscall(s, n);
}
static inline void printint(int64_t v)
{
char neg = 0;
char buf[32] = {};
char *p = &buf[31];
uint64_t u;
if (v < 0) {
u = ~v + 1;
neg = 1;
} else {
u = v;
}
if (u == 0) {
*--p = '0';
goto sig;
}
while (u)
{
*--p = (u % 10) + '0';
u /= 10;
}
sig:
if (neg) {
*--p = '-';
}
printstr(p);
}
static inline void printuint(uint64_t v)
{
char buf[32] = {};
char *p = &buf[31];
if (v == 0)
{
printch('0');
return;
}
while (v)
{
*--p = (v % 10) + '0';
v /= 10;
}
printstr(p);
}
static const char tab[] = "0123456789abcdef";
static inline void printhex(uintptr_t v)
{
if (v == 0)
{
printch('0');
return;
}
char buf[32] = {};
char *p = &buf[31];
while (v)
{
*--p = tab[v & 0x0f];
v >>= 4;
}
printstr(p);
}
#define MAX_BUF_LEN 100
static inline void printbytes(GoSlice *s)
{
printch('[');
int i = 0;
if (s->len > MAX_BUF_LEN)
{
i = s->len - MAX_BUF_LEN;
}
for (; i < s->len; i++)
{
char* bytes = (char*)(s->buf);
printch(tab[(bytes[i] & 0xf0) >> 4]);
printch(tab[bytes[i] & 0x0f]);
if (i != s->len - 1)
printch(',');
}
printch(']');
}
static inline void printgostr(GoString *s)
{
printch('"');
if (s->len < MAX_BUF_LEN)
{
write_syscall(s->buf, s->len);
}
else
{
write_syscall(s->buf, MAX_BUF_LEN);
}
printch('"');
}
static inline void xprintf(const char *fmt, ...)
{
#ifdef DEBUG
__builtin_va_list va;
char buf[256] = {};
char *p = buf;
__builtin_va_start(va, fmt);
for (;;)
{
if (*fmt == 0)
{
break;
}
if (*fmt != '%')
{
*p++ = *fmt++;
continue;
}
*p = 0;
p = buf;
fmt++;
printstr(buf);
switch (*fmt++)
{
case '%':
{
printch('%');
break;
}
case 'g':
{
printgostr(__builtin_va_arg(va, GoString *));
break;
}
case 's':
{
printstr(__builtin_va_arg(va, const char *));
break;
}
case 'd':
{
printint(__builtin_va_arg(va, int64_t));
break;
}
case 'u':
{
printuint(__builtin_va_arg(va, uint64_t));
break;
}
case 'f':
{
printint(__builtin_va_arg(va, double));
break;
}
case 'c':
{
printch((char)(__builtin_va_arg(va, int)));
break;
}
case 'x':
{
printhex(__builtin_va_arg(va, uintptr_t));
break;
}
case 'l':
{
printbytes(__builtin_va_arg(va, GoSlice *));
break;
}
}
}
__builtin_va_end(va);
if (p != buf)
{
*p = 0;
printstr(buf);
}
#endif
}
#endif // XPRINTF_H