int grib_julian_to_datetime(double jd, long *year, long *month, long *day,
                            long *hour, long *minute, long *second) {
  long z, a, alpha, b, c, d, e;
  double dday, dhour, dminute;
  double f;
  jd += 0.5;
  z = (long)jd;
  f = jd - z;
  if (z < 2299161)
    a = z;
  else {
    alpha = (long)((z - 1867216.25) / 36524.25);
    a = z + 1 + alpha - (long)(((double)alpha) / 4);
  }
  b = a + 1524;
  c = (long)((b - 122.1) / 365.25);
  d = (long)(365.25 * c);
  e = (long)(((double)(b - d)) / 30.6001);
  dday = b - d - (long)(30.6001 * e) + f;
  *day = (long)dday;
  dday -= *day;
  dhour = dday * 24;
  *hour = (long)dhour;
  dhour -= *hour;
  dminute = dhour * 60;
  *minute = (long)dminute;
  *second = (long)((dminute - *minute) * 60);
  if (e < 14)
    *month = e - 1;
  else
    *month = e - 13;
  if (*month > 2)
    *year = c - 4716;
  else
    *year = c - 4715;
  return 0;
}


x86 assembly (clang, -O0):
<grib_julian_to_datetime>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
movsd  0xed3(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
cvttsd2si -0x8(%rbp),%rax
mov    %rax,-0x40(%rbp)
movsd  -0x8(%rbp),%xmm0
cvtsi2sdq -0x40(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
cmpq   $0x231519,-0x40(%rbp)
jge    1173 <grib_julian_to_datetime+0x73>
mov    -0x40(%rbp),%rax
mov    %rax,-0x48(%rbp)
jmp    11c4 <grib_julian_to_datetime+0xc4>
cvtsi2sdq -0x40(%rbp),%xmm0
movsd  0xe97(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe83(%rip),%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x50(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
add    -0x50(%rbp),%rax
cvtsi2sdq -0x50(%rbp),%xmm0
movsd  0xe54(%rip),%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rcx
sub    %rcx,%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
add    $0x5f4,%rax
mov    %rax,-0x58(%rbp)
cvtsi2sdq -0x58(%rbp),%xmm0
movsd  0xe60(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe4c(%rip),%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x60(%rbp)
cvtsi2sdq -0x60(%rbp),%xmm1
movsd  0xe31(%rip),%xmm0
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x68(%rbp)
mov    -0x58(%rbp),%rax
sub    -0x68(%rbp),%rax
cvtsi2sd %rax,%xmm0
movsd  0xe07(%rip),%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x70(%rbp)
mov    -0x58(%rbp),%rax
sub    -0x68(%rbp),%rax
cvtsi2sdq -0x70(%rbp),%xmm1
movsd  0xde4(%rip),%xmm0
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rcx
sub    %rcx,%rax
cvtsi2sd %rax,%xmm0
addsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x78(%rbp)
cvttsd2si -0x78(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x20(%rbp),%rax
cvtsi2sdq (%rax),%xmm1
movsd  -0x78(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  0xd92(%rip),%xmm0
mulsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
cvttsd2si -0x80(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x28(%rbp),%rax
cvtsi2sdq (%rax),%xmm1
movsd  -0x80(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  0xd54(%rip),%xmm0
mulsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
cvttsd2si -0x88(%rbp),%rcx
ff ff
mov    -0x30(%rbp),%rax
mov    %rcx,(%rax)
movsd  -0x88(%rbp),%xmm0
ff
mov    -0x30(%rbp),%rax
cvtsi2sdq (%rax),%xmm1
subsd  %xmm1,%xmm0
movsd  0xd1a(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rcx
mov    -0x38(%rbp),%rax
mov    %rcx,(%rax)
cmpq   $0xe,-0x70(%rbp)
jge    1335 <grib_julian_to_datetime+0x235>
mov    -0x70(%rbp),%rcx
sub    $0x1,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
jmp    1344 <grib_julian_to_datetime+0x244>
mov    -0x70(%rbp),%rcx
sub    $0xd,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
cmpq   $0x2,(%rax)
jle    1369 <grib_julian_to_datetime+0x269>
mov    -0x60(%rbp),%rcx
sub    $0x126c,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
jmp    137b <grib_julian_to_datetime+0x27b>
mov    -0x60(%rbp),%rcx
sub    $0x126b,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
xor    %eax,%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<grib_julian_to_datetime>:
push   %rbx
addsd  0xef7(%rip),%xmm0
cvttsd2si %xmm0,%rbx
cvtsi2sd %rbx,%xmm1
cmp    $0x231519,%rbx
jl     1154 <grib_julian_to_datetime+0x54>
movsd  0xee4(%rip),%xmm2
addsd  %xmm1,%xmm2
divsd  0xee0(%rip),%xmm2
cvttsd2si %xmm2,%r10
add    %r10,%rbx
xorps  %xmm2,%xmm2
cvtsi2sd %r10,%xmm2
mulsd  0xed0(%rip),%xmm2
cvttsd2si %xmm2,%rax
sub    %rax,%rbx
add    $0x1,%rbx
add    $0x5f4,%rbx
xorps  %xmm2,%xmm2
cvtsi2sd %rbx,%xmm2
addsd  0xeb5(%rip),%xmm2
movsd  0xeb5(%rip),%xmm3
divsd  %xmm3,%xmm2
cvttsd2si %xmm2,%r10
xorps  %xmm2,%xmm2
cvtsi2sd %r10,%xmm2
mulsd  %xmm3,%xmm2
cvttsd2si %xmm2,%rax
sub    %rax,%rbx
xorps  %xmm2,%xmm2
cvtsi2sd %rbx,%xmm2
movsd  0xe90(%rip),%xmm3
divsd  %xmm3,%xmm2
cvttsd2si %xmm2,%r11
xorps  %xmm2,%xmm2
cvtsi2sd %r11,%xmm2
subsd  %xmm1,%xmm0
mulsd  %xmm3,%xmm2
cvttsd2si %xmm2,%rax
sub    %rax,%rbx
xorps  %xmm1,%xmm1
cvtsi2sd %rbx,%xmm1
addsd  %xmm0,%xmm1
cvttsd2si %xmm1,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
subsd  %xmm0,%xmm1
mulsd  0xe52(%rip),%xmm1
mov    %rax,(%rdx)
cvttsd2si %xmm1,%rax
mov    %rax,(%rcx)
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
subsd  %xmm0,%xmm1
movsd  0xe3b(%rip),%xmm0
mulsd  %xmm0,%xmm1
cvttsd2si %xmm1,%rax
mov    %rax,(%r8)
xorps  %xmm2,%xmm2
cvtsi2sd %rax,%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm1
cvttsd2si %xmm1,%rax
mov    %rax,(%r9)
lea    -0xd(%r11),%rax
lea    -0x1(%r11),%rcx
cmp    $0xe,%r11
cmovl  %rcx,%rax
mov    %rax,(%rsi)
xor    %ecx,%ecx
cmp    $0x3,%rax
setge  %cl
neg    %rcx
lea    (%r10,%rcx,1),%rax
add    $0xffffffffffffed95,%rax
mov    %rax,(%rdi)
xor    %eax,%eax
pop    %rbx
ret

LLVM IR (-O0):
define i32 @grib_julian_to_datetime(double %0, i64* %1, i64* %2, i64* %3, i64* %4, i64* %5, i64* %6) {
%8 = alloca double
%9 = alloca i64*
%10 = alloca i64*
%11 = alloca i64*
%12 = alloca i64*
%13 = alloca i64*
%14 = alloca i64*
%15 = alloca i64
%16 = alloca i64
%17 = alloca i64
%18 = alloca i64
%19 = alloca i64
%20 = alloca i64
%21 = alloca i64
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca double
store double %0, double* %8
store i64* %1, i64** %9
store i64* %2, i64** %10
store i64* %3, i64** %11
store i64* %4, i64** %12
store i64* %5, i64** %13
store i64* %6, i64** %14
%26 = load double, double* %8
%27 = fadd double %26, 5.000000e-01
store double %27, double* %8
%28 = load double, double* %8
%29 = fptosi double %28 to i64
store i64 %29, i64* %15
%30 = load double, double* %8
%31 = load i64, i64* %15
%32 = sitofp i64 %31 to double
%33 = fsub double %30, %32
store double %33, double* %25
%34 = load i64, i64* %15
%35 = icmp slt i64 %34, 2299161
br i1 %35, label %36, label %38
36: ; preds = %7
%37 = load i64, i64* %15
store i64 %37, i64* %16
br label %53
38: ; preds = %7
%39 = load i64, i64* %15
%40 = sitofp i64 %39 to double
%41 = fsub double %40, 0x413C7DD040000000
%42 = fdiv double %41, 0x40E1D58800000000
%43 = fptosi double %42 to i64
store i64 %43, i64* %17
%44 = load i64, i64* %15
%45 = add nsw i64 %44, 1
%46 = load i64, i64* %17
%47 = add nsw i64 %45, %46
%48 = load i64, i64* %17
%49 = sitofp i64 %48 to double
%50 = fdiv double %49, 4.000000e+00
%51 = fptosi double %50 to i64
%52 = sub nsw i64 %47, %51
store i64 %52, i64* %16
br label %53
53: ; preds = %38, %36
%54 = load i64, i64* %16
%55 = add nsw i64 %54, 1524
store i64 %55, i64* %18
%56 = load i64, i64* %18
%57 = sitofp i64 %56 to double
%58 = fsub double %57, 1.221000e+02
%59 = fdiv double %58, 3.652500e+02
%60 = fptosi double %59 to i64
store i64 %60, i64* %19
%61 = load i64, i64* %19
%62 = sitofp i64 %61 to double
%63 = fmul double 3.652500e+02, %62
%64 = fptosi double %63 to i64
store i64 %64, i64* %20
%65 = load i64, i64* %18
%66 = load i64, i64* %20
%67 = sub nsw i64 %65, %66
%68 = sitofp i64 %67 to double
%69 = fdiv double %68, 3.060010e+01
%70 = fptosi double %69 to i64
store i64 %70, i64* %21
%71 = load i64, i64* %18
%72 = load i64, i64* %20
%73 = sub nsw i64 %71, %72
%74 = load i64, i64* %21
%75 = sitofp i64 %74 to double
%76 = fmul double 3.060010e+01, %75
%77 = fptosi double %76 to i64
%78 = sub nsw i64 %73, %77
%79 = sitofp i64 %78 to double
%80 = load double, double* %25
%81 = fadd double %79, %80
store double %81, double* %22
%82 = load double, double* %22
%83 = fptosi double %82 to i64
%84 = load i64*, i64** %11
store i64 %83, i64* %84
%85 = load i64*, i64** %11
%86 = load i64, i64* %85
%87 = sitofp i64 %86 to double
%88 = load double, double* %22
%89 = fsub double %88, %87
store double %89, double* %22
%90 = load double, double* %22
%91 = fmul double %90, 2.400000e+01
store double %91, double* %23
%92 = load double, double* %23
%93 = fptosi double %92 to i64
%94 = load i64*, i64** %12
store i64 %93, i64* %94
%95 = load i64*, i64** %12
%96 = load i64, i64* %95
%97 = sitofp i64 %96 to double
%98 = load double, double* %23
%99 = fsub double %98, %97
store double %99, double* %23
%100 = load double, double* %23
%101 = fmul double %100, 6.000000e+01
store double %101, double* %24
%102 = load double, double* %24
%103 = fptosi double %102 to i64
%104 = load i64*, i64** %13
store i64 %103, i64* %104
%105 = load double, double* %24
%106 = load i64*, i64** %13
%107 = load i64, i64* %106
%108 = sitofp i64 %107 to double
%109 = fsub double %105, %108
%110 = fmul double %109, 6.000000e+01
%111 = fptosi double %110 to i64
%112 = load i64*, i64** %14
store i64 %111, i64* %112
%113 = load i64, i64* %21
%114 = icmp slt i64 %113, 14
br i1 %114, label %115, label %119
115: ; preds = %53
%116 = load i64, i64* %21
%117 = sub nsw i64 %116, 1
%118 = load i64*, i64** %10
store i64 %117, i64* %118
br label %123
119: ; preds = %53
%120 = load i64, i64* %21
%121 = sub nsw i64 %120, 13
%122 = load i64*, i64** %10
store i64 %121, i64* %122
br label %123
123: ; preds = %119, %115
%124 = load i64*, i64** %10
%125 = load i64, i64* %124
%126 = icmp sgt i64 %125, 2
br i1 %126, label %127, label %131
127: ; preds = %123
%128 = load i64, i64* %19
%129 = sub nsw i64 %128, 4716
%130 = load i64*, i64** %9
store i64 %129, i64* %130
br label %135
131: ; preds = %123
%132 = load i64, i64* %19
%133 = sub nsw i64 %132, 4715
%134 = load i64*, i64** %9
store i64 %133, i64* %134
br label %135
135: ; preds = %131, %127
ret i32 0
}

LLVM IR (-O2):
define i32 @grib_julian_to_datetime(double %0, i64* nocapture writeonly %1, i64* nocapture writeonly %2, i64* nocapture writeonly %3, i64* nocapture writeonly %4, i64* nocapture writeonly %5, i64* nocapture writeonly %6) {
%8 = fadd double %0, 5.000000e-01
%9 = fptosi double %8 to i64
%10 = sitofp i64 %9 to double
%11 = icmp slt i64 %9, 2299161
br i1 %11, label %22, label %12
12: ; preds = %7
%13 = fadd double %10, 0xC13C7DD040000000
%14 = fdiv double %13, 0x40E1D58800000000
%15 = fptosi double %14 to i64
%16 = add nuw nsw i64 %9, 1
%17 = add nsw i64 %16, %15
%18 = sitofp i64 %15 to double
%19 = fmul double %18, 2.500000e-01
%20 = fptosi double %19 to i64
%21 = sub i64 %17, %20
br label %22
22: ; preds = %7, %12
%23 = phi i64 [ %21, %12 ], [ %9, %7 ]
%24 = fsub double %8, %10
%25 = add nsw i64 %23, 1524
%26 = sitofp i64 %25 to double
%27 = fadd double %26, -1.221000e+02
%28 = fdiv double %27, 3.652500e+02
%29 = fptosi double %28 to i64
%30 = sitofp i64 %29 to double
%31 = fmul double %30, 3.652500e+02
%32 = fptosi double %31 to i64
%33 = sub nsw i64 %25, %32
%34 = sitofp i64 %33 to double
%35 = fdiv double %34, 3.060010e+01
%36 = fptosi double %35 to i64
%37 = sitofp i64 %36 to double
%38 = fmul double %37, 3.060010e+01
%39 = fptosi double %38 to i64
%40 = sub nsw i64 %33, %39
%41 = sitofp i64 %40 to double
%42 = fadd double %24, %41
%43 = fptosi double %42 to i64
store i64 %43, i64* %3
%44 = sitofp i64 %43 to double
%45 = fsub double %42, %44
%46 = fmul double %45, 2.400000e+01
%47 = fptosi double %46 to i64
store i64 %47, i64* %4
%48 = sitofp i64 %47 to double
%49 = fsub double %46, %48
%50 = fmul double %49, 6.000000e+01
%51 = fptosi double %50 to i64
store i64 %51, i64* %5
%52 = sitofp i64 %51 to double
%53 = fsub double %50, %52
%54 = fmul double %53, 6.000000e+01
%55 = fptosi double %54 to i64
store i64 %55, i64* %6
%56 = icmp slt i64 %36, 14
%57 = select i1 %56, i64 -1, i64 -13
%58 = add nsw i64 %57, %36
store i64 %58, i64* %2
%59 = icmp sgt i64 %58, 2
%60 = select i1 %59, i64 -4716, i64 -4715
%61 = add nsw i64 %60, %29
store i64 %61, i64* %1
ret i32 0
}