mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-01 03:53:33 +00:00
1422e96b4e
There's a new program named ape/ape-m1.c which will be used to build an embeddable binary that can load ape and elf executables. The support is mostly working so far, but still chasing down ABI issues.
84 lines
3.8 KiB
C
84 lines
3.8 KiB
C
#ifndef COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_
|
|
#define COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_
|
|
#include "libc/macros.internal.h"
|
|
#include "libc/nexgen32e/bench.h"
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
/**
|
|
* Shows nanosecond timings histogram for expr at exit().
|
|
*/
|
|
#define COUNTEXPR(expr) \
|
|
COUNTEXPR_(expr, #expr, STRINGIFY(__FILE__), __LINE__, rdtsc, rdtsc, \
|
|
"COUNTEXPR")
|
|
|
|
/**
|
|
* Like COUNTEXPR() but can be used on function calls that return void.
|
|
*/
|
|
#define COUNTSTMT(stmt) \
|
|
(void)COUNTEXPR_((stmt, 0), #stmt, STRINGIFY(__FILE__), __LINE__, rdtsc, \
|
|
rdtsc, "COUNTSTMT")
|
|
|
|
/**
|
|
* Same as COUNTEXPR() but uses Intel's expensive measurement technique.
|
|
*/
|
|
#define BENCHEXPR(expr) \
|
|
COUNTEXPR_(expr, #expr, STRINGIFY(__FILE__), __LINE__, __startbench, \
|
|
__endbench, "BENCHEXPR")
|
|
|
|
#define COUNTEXPR_(expr, code, file, line, start, stop, macro) \
|
|
COUNTEXPR__(expr, STRINGIFY(code), file, line, start, stop, STRINGIFY(macro))
|
|
|
|
#define COUNTEXPR__(expr, code, file, line, start, stop, macro) \
|
|
({ \
|
|
struct countexpr *InfO; \
|
|
uint64_t t1_, t2_, TiCkS, NaNoS; \
|
|
t1_ = start(); \
|
|
asm volatile("" ::: "memory"); \
|
|
autotype(expr) ReS = (expr); \
|
|
asm volatile("" ::: "memory"); \
|
|
t2_ = stop(); \
|
|
TiCkS = t2_ >= t1_ ? t2_ - t1_ : ~t1_ + t2_ + 1; \
|
|
asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \
|
|
".balign\t1\n" \
|
|
"31340:\t.asciz\t" file "\n\t" \
|
|
"31338:\t.asciz\t" code "\n" \
|
|
"31332:\t.asciz\t" macro "\n" \
|
|
".previous\n\t" \
|
|
".section .yoink\n\t" \
|
|
"nopl\tcountexpr_data(%%rip)\n\t" \
|
|
".previous\n\t" \
|
|
".section .sort.data.countexpr.2,\"a\",@progbits\n\t" \
|
|
".balign\t8\n31337:\t" \
|
|
".quad\t" #line "\n\t" \
|
|
".quad\t31340b\n\t" \
|
|
".quad\t31338b\n\t" \
|
|
".quad\t31332b\n\t" \
|
|
".rept\t65\n\t" \
|
|
".quad\t0\n\t" \
|
|
".endr\n\t" \
|
|
".previous\n\t" \
|
|
"lea\t31337b(%%rip),%0" \
|
|
: "=r"(InfO)); \
|
|
/* approximation of round(x*.323018) which is usually */ \
|
|
/* the ratio, between x86 rdtsc ticks and nanoseconds */ \
|
|
NaNoS = (TiCkS * 338709) >> 20; \
|
|
++InfO->logos[NaNoS ? bsrl(NaNoS) + 1 : 0]; \
|
|
ReS; \
|
|
})
|
|
|
|
struct countexpr {
|
|
long line; /* zero for last entry */
|
|
const char *file;
|
|
const char *code;
|
|
const char *macro;
|
|
long logos[65];
|
|
};
|
|
|
|
extern struct countexpr countexpr_data[];
|
|
|
|
void countexpr_report(void);
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_LOG_COUNTEXPR_H_ */
|