#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 */
struct timeval {
  scalar_t__ tv_usec;
  scalar_t__ tv_sec;
};

/* Variables and functions */
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/);
int /*<<< orphan*/ printf(char *);
double dt(char mode) {
  static double t_init;
  double t_now, delta_t;
  struct timeval tv;
  gettimeofday(&tv, 0);
  t_now = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
  delta_t = 0.0;
  switch (mode) {
  case 'i':
    t_init = t_now;
    break;
  case 'e':
    delta_t = t_now - t_init;
    t_init = t_now;
    break;
  case 'r':
    delta_t = t_now - t_init;
    break;
  default:
    printf("Invalid timing mode\n");
  }
  return delta_t;
}


x86 assembly (clang, -O0):
<dt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
lea    -0x28(%rbp),%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
cvtsi2sdq -0x20(%rbp),%xmm1
cvtsi2sdq -0x28(%rbp),%xmm0
movsd  0xeb3(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
movsbl -0x1(%rbp),%eax
mov    %eax,-0x2c(%rbp)
sub    $0x65,%eax
je     11ab <dt+0x8b>
jmp    1177 <dt+0x57>
mov    -0x2c(%rbp),%eax
sub    $0x69,%eax
je     1199 <dt+0x79>
jmp    1188 <dt+0x68>
mov    -0x2c(%rbp),%eax
sub    $0x72,%eax
je     11cf <dt+0xaf>
jmp    11e6 <dt+0xc6>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,0x2e92(%rip)
jmp    11f2 <dt+0xd2>
movsd  -0x10(%rbp),%xmm0
subsd  0x2e80(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,0x2e6e(%rip)
jmp    11f2 <dt+0xd2>
movsd  -0x10(%rbp),%xmm0
subsd  0x2e5c(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    11f2 <dt+0xd2>
lea    0xe1b(%rip),%rdi
call   1030 <printf@plt>
movsd  -0x18(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dt>:
push   %rbx
sub    $0x10,%rsp
mov    %edi,%ebx
mov    %rsp,%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
cvtsi2sdq 0x8(%rsp),%xmm0
cvtsi2sdq (%rsp),%xmm1
mulsd  0xeba(%rip),%xmm1
addsd  %xmm0,%xmm1
cmp    $0x65,%ebx
je     1163 <dt+0x43>
cmp    $0x72,%ebx
je     1179 <dt+0x59>
cmp    $0x69,%ebx
jne    1187 <dt+0x67>
movsd  %xmm1,0x2ed7(%rip)
jmp    1193 <dt+0x73>
movapd %xmm1,%xmm0
subsd  0x2ec9(%rip),%xmm0
movsd  %xmm1,0x2ec1(%rip)
jmp    1197 <dt+0x77>
subsd  0x2eb7(%rip),%xmm1
movapd %xmm1,%xmm0
jmp    1197 <dt+0x77>
lea    0xe7a(%rip),%rdi
call   1030 <puts@plt>
xorpd  %xmm0,%xmm0
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
%struct.timeval = type { i64, i64 }
@dt.t_init = internal global double 0.000000e+00
@.str = [21 x i8] c"Invalid timing mode\0A\00"
define double @dt(i8 signext %0) {
%2 = alloca i8
%3 = alloca double
%4 = alloca double
%5 = alloca %struct.timeval
store i8 %0, i8* %2
%6 = call i32 @gettimeofday(%struct.timeval* %5, i32 0)
%7 = getelementptr inbounds %struct.timeval, %struct.timeval* %5, i32 0, i32 1
%8 = load i64, i64* %7
%9 = sitofp i64 %8 to double
%10 = getelementptr inbounds %struct.timeval, %struct.timeval* %5, i32 0, i32 0
%11 = load i64, i64* %10
%12 = sitofp i64 %11 to double
%13 = call double @llvm.fmuladd.f64(double %12, double 0x3EB0C6F7A0B5ED8D, double %9)
store double %13, double* %3
store double 0.000000e+00, double* %4
%14 = load i8, i8* %2
%15 = sext i8 %14 to i32
switch i32 %15, label %27 [
i32 105, label %16
i32 101, label %18
i32 114, label %23
]
16: ; preds = %1
%17 = load double, double* %3
store double %17, double* @dt.t_init
br label %29
18: ; preds = %1
%19 = load double, double* %3
%20 = load double, double* @dt.t_init
%21 = fsub double %19, %20
store double %21, double* %4
%22 = load double, double* %3
store double %22, double* @dt.t_init
br label %29
23: ; preds = %1
%24 = load double, double* %3
%25 = load double, double* @dt.t_init
%26 = fsub double %24, %25
store double %26, double* %4
br label %29
27: ; preds = %1
%28 = call i32 @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0))
br label %29
29: ; preds = %27, %23, %18, %16
%30 = load double, double* %4
ret double %30
}

LLVM IR (-O2):
%struct.timeval = type { i64, i64 }
@dt.t_init = internal unnamed_addr global double 0.000000e+00
@str = [20 x i8] c"Invalid timing mode\00"
define double @dt(i8 signext %0) {
%2 = alloca %struct.timeval
%3 = bitcast %struct.timeval* %2 to i8*
%4 = call i32 @gettimeofday(%struct.timeval* %2, i32 0)
%5 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 1
%6 = load i64, i64* %5
%7 = sitofp i64 %6 to double
%8 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 0
%9 = load i64, i64* %8
%10 = sitofp i64 %9 to double
%11 = call double @llvm.fmuladd.f64(double %10, double 0x3EB0C6F7A0B5ED8D, double %7)
%12 = sext i8 %0 to i32
switch i32 %12, label %20 [
i32 105, label %13
i32 101, label %14
i32 114, label %17
]
13: ; preds = %1
store double %11, double* @dt.t_init
br label %22
14: ; preds = %1
%15 = load double, double* @dt.t_init
%16 = fsub double %11, %15
store double %11, double* @dt.t_init
br label %22
17: ; preds = %1
%18 = load double, double* @dt.t_init
%19 = fsub double %11, %18
br label %22
20: ; preds = %1
%21 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @str, i64 0, i64 0))
br label %22
22: ; preds = %20, %17, %14, %13
%23 = phi double [ 0.000000e+00, %20 ], [ %19, %17 ], [ %16, %14 ], [ 0.000000e+00, %13 ]
ret double %23
}