#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 timespec {
  int tv_nsec;
  int tv_sec;
};

/* Variables and functions */
int /*<<< orphan*/ CLOCK_MONOTONIC_RAW;
int /*<<< orphan*/ clock_gettime(int /*<<< orphan*/, struct timespec *);
long labs(long);
int ap_utils_timespec_set(struct timespec *ts, int mode, int msec) {
  long tmp;
  if (msec < 0)
    return 0;
  switch (mode) {
  case 0:
    ts->tv_nsec += msec * 1000000l;
    break;
  case 1:
    ts->tv_nsec -= msec * 1000000l;
    break;
  case 2:
    clock_gettime(CLOCK_MONOTONIC_RAW, ts);
    ts->tv_nsec += msec * 1000000l;
    break;
  case 3:
    ts->tv_sec = msec / 1000;
    ts->tv_nsec = 1000000000l * (msec % 1000l);
    return 1;
  default:
    return 0;
  }
  if (ts->tv_nsec >= 1000000000l) {
    tmp = ts->tv_nsec / 1000000000l;
    ts->tv_nsec -= tmp * 1000000000l;
    ts->tv_sec += tmp;
  } else if (ts->tv_nsec < 0l) {
    tmp = labs(ts->tv_nsec) / 1000000000l;
    ts->tv_nsec = 1000000000l + ts->tv_nsec + tmp * 1000000000l;
    ts->tv_sec -= tmp;
  }
  return 1;
}


x86 assembly (clang, -O0):
<ap_utils_timespec_set>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
cmpl   $0x0,-0x18(%rbp)
jge    1148 <ap_utils_timespec_set+0x28>
movl   $0x0,-0x4(%rbp)
jmp    12d8 <ap_utils_timespec_set+0x1b8>
mov    -0x14(%rbp),%eax
mov    %rax,-0x28(%rbp)
sub    $0x3,%rax
ja     1210 <ap_utils_timespec_set+0xf0>
mov    -0x28(%rbp),%rax
lea    0xe9c(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movslq -0x18(%rbp),%rax
imul   $0xf4240,%rax,%rdx
mov    -0x10(%rbp),%rax
movslq (%rax),%rcx
add    %rdx,%rcx
mov    %ecx,(%rax)
jmp    121c <ap_utils_timespec_set+0xfc>
movslq -0x18(%rbp),%rax
imul   $0xf4240,%rax,%rdx
mov    -0x10(%rbp),%rax
movslq (%rax),%rcx
sub    %rdx,%rcx
mov    %ecx,(%rax)
jmp    121c <ap_utils_timespec_set+0xfc>
mov    0x2e3c(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rsi
call   1030 <clock_gettime@plt>
movslq -0x18(%rbp),%rax
imul   $0xf4240,%rax,%rdx
mov    -0x10(%rbp),%rax
movslq (%rax),%rcx
add    %rdx,%rcx
mov    %ecx,(%rax)
jmp    121c <ap_utils_timespec_set+0xfc>
mov    -0x18(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x4(%rax)
movslq -0x18(%rbp),%rax
mov    $0x3e8,%ecx
cqto
idiv   %rcx
imul   $0x3b9aca00,%rdx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x1,-0x4(%rbp)
jmp    12d8 <ap_utils_timespec_set+0x1b8>
movl   $0x0,-0x4(%rbp)
jmp    12d8 <ap_utils_timespec_set+0x1b8>
mov    -0x10(%rbp),%rax
movslq (%rax),%rax
cmp    $0x3b9aca00,%rax
jl     126f <ap_utils_timespec_set+0x14f>
mov    -0x10(%rbp),%rax
movslq (%rax),%rax
mov    $0x3b9aca00,%ecx
cqto
idiv   %rcx
mov    %rax,-0x20(%rbp)
imul   $0x3b9aca00,-0x20(%rbp),%rdx
3b
mov    -0x10(%rbp),%rax
movslq (%rax),%rcx
sub    %rdx,%rcx
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rdx
mov    -0x10(%rbp),%rax
movslq 0x4(%rax),%rcx
add    %rdx,%rcx
mov    %ecx,0x4(%rax)
jmp    12d1 <ap_utils_timespec_set+0x1b1>
mov    -0x10(%rbp),%rax
movslq (%rax),%rax
cmp    $0x0,%rax
jge    12cc <ap_utils_timespec_set+0x1ac>
mov    -0x10(%rbp),%rax
movslq (%rax),%rdi
call   1040 <labs@plt>
mov    $0x3b9aca00,%ecx
cqto
idiv   %rcx
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movslq (%rax),%rax
add    $0x3b9aca00,%rax
imul   $0x3b9aca00,-0x20(%rbp),%rcx
3b
add    %rcx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rdx
mov    -0x10(%rbp),%rax
movslq 0x4(%rax),%rcx
sub    %rdx,%rcx
mov    %ecx,0x4(%rax)
jmp    12d1 <ap_utils_timespec_set+0x1b1>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ap_utils_timespec_set>:
push   %rbp
push   %rbx
push   %rax
xor    %eax,%eax
test   %edx,%edx
js     11dc <ap_utils_timespec_set+0xcc>
cmp    $0x3,%esi
ja     11dc <ap_utils_timespec_set+0xcc>
mov    %edx,%ebp
mov    %rdi,%rbx
mov    %esi,%eax
lea    0xecc(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
imul   $0xfff0bdc0,%ebp,%ecx
jmp    115c <ap_utils_timespec_set+0x4c>
mov    0x2e9c(%rip),%rax
mov    (%rax),%edi
mov    %rbx,%rsi
call   1030 <clock_gettime@plt>
imul   $0xf4240,%ebp,%ecx
add    (%rbx),%ecx
mov    %ecx,(%rbx)
cmp    $0x3b9aca00,%ecx
jl     1187 <ap_utils_timespec_set+0x77>
mov    %ecx,%eax
shr    $0x9,%eax
imul   $0x44b83,%rax,%rax
shr    $0x27,%rax
imul   $0xc4653600,%eax,%edx
add    %ecx,%edx
mov    %edx,(%rbx)
add    %eax,0x4(%rbx)
jmp    11d7 <ap_utils_timespec_set+0xc7>
mov    $0x1,%eax
test   %ecx,%ecx
jns    11dc <ap_utils_timespec_set+0xcc>
mov    %ecx,%edx
neg    %edx
shr    $0x9,%edx
imul   $0x44b83,%rdx,%rdx
shr    $0x27,%rdx
imul   $0x3b9aca00,%edx,%esi
add    %esi,%ecx
add    $0x3b9aca00,%ecx
mov    %ecx,(%rbx)
sub    %edx,0x4(%rbx)
jmp    11dc <ap_utils_timespec_set+0xcc>
mov    %ebp,%eax
imul   $0x10624dd3,%rax,%rax
shr    $0x26,%rax
mov    %eax,0x4(%rbx)
imul   $0x3e8,%eax,%eax
sub    %eax,%ebp
imul   $0x3b9aca00,%ebp,%eax
mov    %eax,(%rbx)
mov    $0x1,%eax
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
%struct.timespec = type { i32, i32 }
@CLOCK_MONOTONIC_RAW = global i32 0
define i32 @ap_utils_timespec_set(%struct.timespec* %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca %struct.timespec*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i64
store %struct.timespec* %0, %struct.timespec** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
%9 = load i32, i32* %7
%10 = icmp slt i32 %9, 0
br i1 %10, label %11, label %12
11: ; preds = %3
store i32 0, i32* %4
br label %120
12: ; preds = %3
%13 = load i32, i32* %6
switch i32 %13, label %59 [
i32 0, label %14
i32 1, label %24
i32 2, label %34
i32 3, label %47
]
14: ; preds = %12
%15 = load i32, i32* %7
%16 = sext i32 %15 to i64
%17 = mul nsw i64 %16, 1000000
%18 = load %struct.timespec*, %struct.timespec** %5
%19 = getelementptr inbounds %struct.timespec, %struct.timespec* %18, i32 0, i32 0
%20 = load i32, i32* %19
%21 = sext i32 %20 to i64
%22 = add nsw i64 %21, %17
%23 = trunc i64 %22 to i32
store i32 %23, i32* %19
br label %60
24: ; preds = %12
%25 = load i32, i32* %7
%26 = sext i32 %25 to i64
%27 = mul nsw i64 %26, 1000000
%28 = load %struct.timespec*, %struct.timespec** %5
%29 = getelementptr inbounds %struct.timespec, %struct.timespec* %28, i32 0, i32 0
%30 = load i32, i32* %29
%31 = sext i32 %30 to i64
%32 = sub nsw i64 %31, %27
%33 = trunc i64 %32 to i32
store i32 %33, i32* %29
br label %60
34: ; preds = %12
%35 = load i32, i32* @CLOCK_MONOTONIC_RAW
%36 = load %struct.timespec*, %struct.timespec** %5
%37 = call i32 @clock_gettime(i32 %35, %struct.timespec* %36)
%38 = load i32, i32* %7
%39 = sext i32 %38 to i64
%40 = mul nsw i64 %39, 1000000
%41 = load %struct.timespec*, %struct.timespec** %5
%42 = getelementptr inbounds %struct.timespec, %struct.timespec* %41, i32 0, i32 0
%43 = load i32, i32* %42
%44 = sext i32 %43 to i64
%45 = add nsw i64 %44, %40
%46 = trunc i64 %45 to i32
store i32 %46, i32* %42
br label %60
47: ; preds = %12
%48 = load i32, i32* %7
%49 = sdiv i32 %48, 1000
%50 = load %struct.timespec*, %struct.timespec** %5
%51 = getelementptr inbounds %struct.timespec, %struct.timespec* %50, i32 0, i32 1
store i32 %49, i32* %51
%52 = load i32, i32* %7
%53 = sext i32 %52 to i64
%54 = srem i64 %53, 1000
%55 = mul nsw i64 1000000000, %54
%56 = trunc i64 %55 to i32
%57 = load %struct.timespec*, %struct.timespec** %5
%58 = getelementptr inbounds %struct.timespec, %struct.timespec* %57, i32 0, i32 0
store i32 %56, i32* %58
store i32 1, i32* %4
br label %120
59: ; preds = %12
store i32 0, i32* %4
br label %120
60: ; preds = %34, %24, %14
%61 = load %struct.timespec*, %struct.timespec** %5
%62 = getelementptr inbounds %struct.timespec, %struct.timespec* %61, i32 0, i32 0
%63 = load i32, i32* %62
%64 = sext i32 %63 to i64
%65 = icmp sge i64 %64, 1000000000
br i1 %65, label %66, label %87
66: ; preds = %60
%67 = load %struct.timespec*, %struct.timespec** %5
%68 = getelementptr inbounds %struct.timespec, %struct.timespec* %67, i32 0, i32 0
%69 = load i32, i32* %68
%70 = sext i32 %69 to i64
%71 = sdiv i64 %70, 1000000000
store i64 %71, i64* %8
%72 = load i64, i64* %8
%73 = mul nsw i64 %72, 1000000000
%74 = load %struct.timespec*, %struct.timespec** %5
%75 = getelementptr inbounds %struct.timespec, %struct.timespec* %74, i32 0, i32 0
%76 = load i32, i32* %75
%77 = sext i32 %76 to i64
%78 = sub nsw i64 %77, %73
%79 = trunc i64 %78 to i32
store i32 %79, i32* %75
%80 = load i64, i64* %8
%81 = load %struct.timespec*, %struct.timespec** %5
%82 = getelementptr inbounds %struct.timespec, %struct.timespec* %81, i32 0, i32 1
%83 = load i32, i32* %82
%84 = sext i32 %83 to i64
%85 = add nsw i64 %84, %80
%86 = trunc i64 %85 to i32
store i32 %86, i32* %82
br label %119
87: ; preds = %60
%88 = load %struct.timespec*, %struct.timespec** %5
%89 = getelementptr inbounds %struct.timespec, %struct.timespec* %88, i32 0, i32 0
%90 = load i32, i32* %89
%91 = sext i32 %90 to i64
%92 = icmp slt i64 %91, 0
br i1 %92, label %93, label %118
93: ; preds = %87
%94 = load %struct.timespec*, %struct.timespec** %5
%95 = getelementptr inbounds %struct.timespec, %struct.timespec* %94, i32 0, i32 0
%96 = load i32, i32* %95
%97 = sext i32 %96 to i64
%98 = call i64 @labs(i64 %97)
%99 = sdiv i64 %98, 1000000000
store i64 %99, i64* %8
%100 = load %struct.timespec*, %struct.timespec** %5
%101 = getelementptr inbounds %struct.timespec, %struct.timespec* %100, i32 0, i32 0
%102 = load i32, i32* %101
%103 = sext i32 %102 to i64
%104 = add nsw i64 1000000000, %103
%105 = load i64, i64* %8
%106 = mul nsw i64 %105, 1000000000
%107 = add nsw i64 %104, %106
%108 = trunc i64 %107 to i32
%109 = load %struct.timespec*, %struct.timespec** %5
%110 = getelementptr inbounds %struct.timespec, %struct.timespec* %109, i32 0, i32 0
store i32 %108, i32* %110
%111 = load i64, i64* %8
%112 = load %struct.timespec*, %struct.timespec** %5
%113 = getelementptr inbounds %struct.timespec, %struct.timespec* %112, i32 0, i32 1
%114 = load i32, i32* %113
%115 = sext i32 %114 to i64
%116 = sub nsw i64 %115, %111
%117 = trunc i64 %116 to i32
store i32 %117, i32* %113
br label %118
118: ; preds = %93, %87
br label %119
119: ; preds = %118, %66
store i32 1, i32* %4
br label %120
120: ; preds = %119, %59, %47, %11
%121 = load i32, i32* %4
ret i32 %121
}

LLVM IR (-O2):
%struct.timespec = type { i32, i32 }
@CLOCK_MONOTONIC_RAW = global i32 0
define i32 @ap_utils_timespec_set(%struct.timespec* %0, i32 %1, i32 %2) {
%4 = icmp slt i32 %2, 0
br i1 %4, label %51, label %5
5: ; preds = %3
switch i32 %1, label %51 [
i32 0, label %6
i32 1, label %11
i32 2, label %16
i32 3, label %23
]
6: ; preds = %5
%7 = mul i32 %2, 1000000
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
%9 = load i32, i32* %8
%10 = add i32 %9, %7
store i32 %10, i32* %8
br label %29
11: ; preds = %5
%12 = mul i32 %2, -1000000
%13 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
%14 = load i32, i32* %13
%15 = add i32 %14, %12
store i32 %15, i32* %13
br label %29
16: ; preds = %5
%17 = load i32, i32* @CLOCK_MONOTONIC_RAW
%18 = tail call i32 @clock_gettime(i32 %17, %struct.timespec* %0)
%19 = mul i32 %2, 1000000
%20 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
%21 = load i32, i32* %20
%22 = add i32 %21, %19
store i32 %22, i32* %20
br label %29
23: ; preds = %5
%24 = udiv i32 %2, 1000
%25 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 1
store i32 %24, i32* %25
%26 = urem i32 %2, 1000
%27 = mul i32 %26, 1000000000
%28 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
store i32 %27, i32* %28
br label %51
29: ; preds = %16, %11, %6
%30 = phi i32 [ %22, %16 ], [ %15, %11 ], [ %10, %6 ]
%31 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
%32 = icmp sgt i32 %30, 999999999
br i1 %32, label %33, label %40
33: ; preds = %29
%34 = udiv i32 %30, 1000000000
%35 = mul nsw i32 %34, -1000000000
%36 = add nsw i32 %35, %30
store i32 %36, i32* %31
%37 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 1
%38 = load i32, i32* %37
%39 = add i32 %38, %34
store i32 %39, i32* %37
br label %51
40: ; preds = %29
%41 = icmp slt i32 %30, 0
br i1 %41, label %42, label %51
42: ; preds = %40
%43 = sub i32 0, %30
%44 = udiv i32 %43, 1000000000
%45 = add nsw i32 %30, 1000000000
%46 = mul nuw nsw i32 %44, 1000000000
%47 = add i32 %45, %46
store i32 %47, i32* %31
%48 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 1
%49 = load i32, i32* %48
%50 = sub i32 %49, %44
store i32 %50, i32* %48
br label %51
51: ; preds = %33, %42, %40, %5, %3, %23
%52 = phi i32 [ 1, %23 ], [ 0, %3 ], [ 0, %5 ], [ 1, %40 ], [ 1, %42 ], [ 1, %33 ]
ret i32 %52
}