#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef unsigned long uint64_t;
struct timespec {
  unsigned long tv_sec;
  double tv_nsec;
};

/* Variables and functions */
int /*<<< orphan*/ CLOCK_REALTIME;
int /*<<< orphan*/ clock_gettime(int /*<<< orphan*/, struct timespec *);
uint64_t get_us_time() {
  struct timespec spec;
  clock_gettime(CLOCK_REALTIME, &spec);
  return spec.tv_sec * 1000000ul + spec.tv_nsec / 1.0e3;
}


x86 assembly (clang, -O0):
<get_us_time>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    0x2ec1(%rip),%rax
mov    (%rax),%edi
lea    -0x10(%rbp),%rsi
call   1030 <clock_gettime@plt>
mov    -0x10(%rbp),%rax
imul   $0xf4240,%rax,%rax
movq   %rax,%xmm0
movaps 0xebf(%rip),%xmm1
punpckldq %xmm1,%xmm0
movapd 0xec3(%rip),%xmm1
subpd  %xmm1,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x8(%rbp),%xmm1
movsd  0xeb7(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movaps %xmm0,%xmm1
cvttsd2si %xmm1,%rax
mov    %rax,%rdx
sar    $0x3f,%rdx
movsd  0xea0(%rip),%xmm1
subsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rcx
and    %rdx,%rcx
or     %rcx,%rax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_us_time>:
sub    $0x18,%rsp
mov    0x2ec5(%rip),%rax
mov    (%rax),%edi
lea    0x8(%rsp),%rsi
call   1030 <clock_gettime@plt>
imul   $0xf4240,0x8(%rsp),%rax
movq   %rax,%xmm0
punpckldq 0xec3(%rip),%xmm0
subpd  0xecb(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
movsd  0x10(%rsp),%xmm2
divsd  0xec5(%rip),%xmm2
addsd  %xmm0,%xmm1
addsd  %xmm1,%xmm2
cvttsd2si %xmm2,%rcx
mov    %rcx,%rdx
sar    $0x3f,%rdx
subsd  0xeb1(%rip),%xmm2
cvttsd2si %xmm2,%rax
and    %rdx,%rax
or     %rcx,%rax
add    $0x18,%rsp
ret

LLVM IR (-O0):
%struct.timespec = type { i64, double }
@CLOCK_REALTIME = global i32 0
define i64 @get_us_time() {
%1 = alloca %struct.timespec
%2 = load i32, i32* @CLOCK_REALTIME
%3 = call i32 @clock_gettime(i32 %2, %struct.timespec* %1)
%4 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i32 0, i32 0
%5 = load i64, i64* %4
%6 = mul i64 %5, 1000000
%7 = uitofp i64 %6 to double
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i32 0, i32 1
%9 = load double, double* %8
%10 = fdiv double %9, 1.000000e+03
%11 = fadd double %7, %10
%12 = fptoui double %11 to i64
ret i64 %12
}

LLVM IR (-O2):
%struct.timespec = type { i64, double }
@CLOCK_REALTIME = global i32 0
define i64 @get_us_time() {
%1 = alloca %struct.timespec
%2 = bitcast %struct.timespec* %1 to i8*
%3 = load i32, i32* @CLOCK_REALTIME
%4 = call i32 @clock_gettime(i32 %3, %struct.timespec* %1)
%5 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 0
%6 = load i64, i64* %5
%7 = mul i64 %6, 1000000
%8 = uitofp i64 %7 to double
%9 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 1
%10 = load double, double* %9
%11 = fdiv double %10, 1.000000e+03
%12 = fadd double %11, %8
%13 = fptoui double %12 to i64
ret i64 %13
}