void rgb_to_hsv(unsigned short r, unsigned short g, unsigned short b, int *h,
                double *s, double *v) {
  double R, G, B, H, S, V;
  double cmax, cmin;
  double cmm;
  int imax;
  R = ((double)r) / 65535.0;
  G = ((double)g) / 65535.0;
  B = ((double)b) / 65535.0;
  cmax = R;
  cmin = G;
  imax = 1;
  if (cmax < G) {
    cmax = G;
    cmin = R;
    imax = 2;
  }
  if (cmax < B) {
    cmax = B;
    imax = 3;
  }
  if (cmin > B) {
    cmin = B;
  }
  cmm = cmax - cmin;
  V = cmax;
  if (cmm == 0)
    S = H = 0;
  else {
    S = cmm / cmax;
    if (imax == 1)
      H = (G - B) / cmm;
    else if (imax == 2)
      H = 2.0 + (B - R) / cmm;
    else
      H = 4.0 + (R - G) / cmm;
    if (H < 0)
      H += 6.0;
  }
  *h = (H * 60.0);
  *s = S;
  *v = V;
}


x86 assembly (clang, -O0):
<rgb_to_hsv>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %si,%dx
mov    %di,%si
mov    %si,-0x2(%rbp)
mov    %dx,-0x4(%rbp)
mov    %ax,-0x6(%rbp)
mov    %rcx,-0x10(%rbp)
mov    %r8,-0x18(%rbp)
mov    %r9,-0x20(%rbp)
movzwl -0x2(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xecb(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movzwl -0x4(%rbp),%eax
cvtsi2sd %eax,%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movzwl -0x6(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xea1(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movl   $0x1,-0x6c(%rbp)
movsd  -0x58(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11b2 <rgb_to_hsv+0xb2>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movl   $0x2,-0x6c(%rbp)
movsd  -0x58(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11d7 <rgb_to_hsv+0xd7>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movl   $0x3,-0x6c(%rbp)
movsd  -0x60(%rbp),%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    11f1 <rgb_to_hsv+0xf1>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x58(%rbp),%xmm0
subsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x68(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1237 <rgb_to_hsv+0x137>
jp     1237 <rgb_to_hsv+0x137>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    12e2 <rgb_to_hsv+0x1e2>
movsd  -0x68(%rbp),%xmm0
divsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
cmpl   $0x1,-0x6c(%rbp)
jne    1269 <rgb_to_hsv+0x169>
movsd  -0x30(%rbp),%xmm0
subsd  -0x38(%rbp),%xmm0
divsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    12bd <rgb_to_hsv+0x1bd>
cmpl   $0x2,-0x6c(%rbp)
jne    1298 <rgb_to_hsv+0x198>
movsd  -0x38(%rbp),%xmm1
subsd  -0x28(%rbp),%xmm1
divsd  -0x68(%rbp),%xmm1
movsd  0xd86(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    12b8 <rgb_to_hsv+0x1b8>
movsd  -0x28(%rbp),%xmm1
subsd  -0x30(%rbp),%xmm1
divsd  -0x68(%rbp),%xmm1
movsd  0xd59(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    12bd <rgb_to_hsv+0x1bd>
xorps  %xmm0,%xmm0
ucomisd -0x40(%rbp),%xmm0
jbe    12dd <rgb_to_hsv+0x1dd>
movsd  0xd45(%rip),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    12e2 <rgb_to_hsv+0x1e2>
movsd  0xd36(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
cvttsd2si %xmm0,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movsd  -0x48(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x50(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<rgb_to_hsv>:
movd   %edi,%xmm0
pinsrw $0x2,%esi,%xmm0
cvtdq2pd %xmm0,%xmm2
divpd  0xeeb(%rip),%xmm2
cvtsi2sd %edx,%xmm3
divsd  0xeef(%rip),%xmm3
movapd %xmm2,%xmm4
unpckhpd %xmm2,%xmm4
movapd %xmm4,%xmm6
maxsd  %xmm2,%xmm6
movapd %xmm2,%xmm1
minsd  %xmm4,%xmm1
movapd %xmm3,%xmm0
maxsd  %xmm6,%xmm0
movapd %xmm3,%xmm5
minsd  %xmm1,%xmm5
movapd %xmm0,%xmm1
subsd  %xmm5,%xmm1
xorpd  %xmm7,%xmm7
ucomisd %xmm7,%xmm1
xorpd  %xmm5,%xmm5
jne    1161 <rgb_to_hsv+0x61>
jnp    11d5 <rgb_to_hsv+0xd5>
xor    %edx,%edx
ucomisd %xmm2,%xmm4
seta   %dl
add    $0x1,%edx
ucomisd %xmm6,%xmm3
mov    $0x3,%eax
cmovbe %edx,%eax
cmp    $0x2,%eax
je     1191 <rgb_to_hsv+0x91>
cmp    $0x1,%eax
jne    11a7 <rgb_to_hsv+0xa7>
subsd  %xmm3,%xmm4
divsd  %xmm1,%xmm4
movapd %xmm4,%xmm5
jmp    11bb <rgb_to_hsv+0xbb>
subsd  %xmm2,%xmm3
divsd  %xmm1,%xmm3
addsd  0xe77(%rip),%xmm3
movapd %xmm3,%xmm5
jmp    11bb <rgb_to_hsv+0xbb>
subsd  %xmm4,%xmm2
divsd  %xmm1,%xmm2
addsd  0xe69(%rip),%xmm2
movapd %xmm2,%xmm5
divsd  %xmm0,%xmm1
xorpd  %xmm2,%xmm2
ucomisd %xmm5,%xmm2
jbe    11d1 <rgb_to_hsv+0xd1>
addsd  0xe57(%rip),%xmm5
movapd %xmm1,%xmm7
mulsd  0xe53(%rip),%xmm5
cvttsd2si %xmm5,%eax
mov    %eax,(%rcx)
movsd  %xmm7,(%r8)
movsd  %xmm0,(%r9)
ret

LLVM IR (-O0):
define void @rgb_to_hsv(i16 zeroext %0, i16 zeroext %1, i16 zeroext %2, i32* %3, double* %4, double* %5) {
%7 = alloca i16
%8 = alloca i16
%9 = alloca i16
%10 = alloca i32*
%11 = alloca double*
%12 = alloca double*
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
%21 = alloca double
%22 = alloca i32
store i16 %0, i16* %7
store i16 %1, i16* %8
store i16 %2, i16* %9
store i32* %3, i32** %10
store double* %4, double** %11
store double* %5, double** %12
%23 = load i16, i16* %7
%24 = uitofp i16 %23 to double
%25 = fdiv double %24, 6.553500e+04
store double %25, double* %13
%26 = load i16, i16* %8
%27 = uitofp i16 %26 to double
%28 = fdiv double %27, 6.553500e+04
store double %28, double* %14
%29 = load i16, i16* %9
%30 = uitofp i16 %29 to double
%31 = fdiv double %30, 6.553500e+04
store double %31, double* %15
%32 = load double, double* %13
store double %32, double* %19
%33 = load double, double* %14
store double %33, double* %20
store i32 1, i32* %22
%34 = load double, double* %19
%35 = load double, double* %14
%36 = fcmp olt double %34, %35
br i1 %36, label %37, label %40
37: ; preds = %6
%38 = load double, double* %14
store double %38, double* %19
%39 = load double, double* %13
store double %39, double* %20
store i32 2, i32* %22
br label %40
40: ; preds = %37, %6
%41 = load double, double* %19
%42 = load double, double* %15
%43 = fcmp olt double %41, %42
br i1 %43, label %44, label %46
44: ; preds = %40
%45 = load double, double* %15
store double %45, double* %19
store i32 3, i32* %22
br label %46
46: ; preds = %44, %40
%47 = load double, double* %20
%48 = load double, double* %15
%49 = fcmp ogt double %47, %48
br i1 %49, label %50, label %52
50: ; preds = %46
%51 = load double, double* %15
store double %51, double* %20
br label %52
52: ; preds = %50, %46
%53 = load double, double* %19
%54 = load double, double* %20
%55 = fsub double %53, %54
store double %55, double* %21
%56 = load double, double* %19
store double %56, double* %18
%57 = load double, double* %21
%58 = fcmp oeq double %57, 0.000000e+00
br i1 %58, label %59, label %60
59: ; preds = %52
store double 0.000000e+00, double* %16
store double 0.000000e+00, double* %17
br label %97
60: ; preds = %52
%61 = load double, double* %21
%62 = load double, double* %19
%63 = fdiv double %61, %62
store double %63, double* %17
%64 = load i32, i32* %22
%65 = icmp eq i32 %64, 1
br i1 %65, label %66, label %72
66: ; preds = %60
%67 = load double, double* %14
%68 = load double, double* %15
%69 = fsub double %67, %68
%70 = load double, double* %21
%71 = fdiv double %69, %70
store double %71, double* %16
br label %90
72: ; preds = %60
%73 = load i32, i32* %22
%74 = icmp eq i32 %73, 2
br i1 %74, label %75, label %82
75: ; preds = %72
%76 = load double, double* %15
%77 = load double, double* %13
%78 = fsub double %76, %77
%79 = load double, double* %21
%80 = fdiv double %78, %79
%81 = fadd double 2.000000e+00, %80
store double %81, double* %16
br label %89
82: ; preds = %72
%83 = load double, double* %13
%84 = load double, double* %14
%85 = fsub double %83, %84
%86 = load double, double* %21
%87 = fdiv double %85, %86
%88 = fadd double 4.000000e+00, %87
store double %88, double* %16
br label %89
89: ; preds = %82, %75
br label %90
90: ; preds = %89, %66
%91 = load double, double* %16
%92 = fcmp olt double %91, 0.000000e+00
br i1 %92, label %93, label %96
93: ; preds = %90
%94 = load double, double* %16
%95 = fadd double %94, 6.000000e+00
store double %95, double* %16
br label %96
96: ; preds = %93, %90
br label %97
97: ; preds = %96, %59
%98 = load double, double* %16
%99 = fmul double %98, 6.000000e+01
%100 = fptosi double %99 to i32
%101 = load i32*, i32** %10
store i32 %100, i32* %101
%102 = load double, double* %17
%103 = load double*, double** %11
store double %102, double* %103
%104 = load double, double* %18
%105 = load double*, double** %12
store double %104, double* %105
ret void
}

LLVM IR (-O2):
define void @rgb_to_hsv(i16 zeroext %0, i16 zeroext %1, i16 zeroext %2, i32* nocapture writeonly %3, double* nocapture writeonly %4, double* nocapture writeonly %5) {
%7 = insertelement <2 x i16> poison, i16 %0, i64 0
%8 = insertelement <2 x i16> %7, i16 %1, i64 1
%9 = uitofp <2 x i16> %8 to <2 x double>
%10 = fdiv <2 x double> %9, <double 6.553500e+04, double 6.553500e+04>
%11 = uitofp i16 %2 to double
%12 = fdiv double %11, 6.553500e+04
%13 = extractelement <2 x double> %10, i64 0
%14 = extractelement <2 x double> %10, i64 1
%15 = fcmp olt double %13, %14
%16 = select i1 %15, double %14, double %13
%17 = select i1 %15, double %13, double %14
%18 = fcmp olt double %16, %12
%19 = select i1 %18, double %12, double %16
%20 = fcmp ogt double %17, %12
%21 = select i1 %20, double %12, double %17
%22 = fsub double %19, %21
%23 = fcmp oeq double %22, 0.000000e+00
br i1 %23, label %44, label %24
24: ; preds = %6
%25 = select i1 %15, i32 2, i32 1
%26 = select i1 %18, i32 3, i32 %25
%27 = fdiv double %22, %19
switch i32 %26, label %35 [
i32 1, label %28
i32 2, label %31
]
28: ; preds = %24
%29 = fsub double %14, %12
%30 = fdiv double %29, %22
br label %39
31: ; preds = %24
%32 = fsub double %12, %13
%33 = fdiv double %32, %22
%34 = fadd double %33, 2.000000e+00
br label %39
35: ; preds = %24
%36 = fsub double %13, %14
%37 = fdiv double %36, %22
%38 = fadd double %37, 4.000000e+00
br label %39
39: ; preds = %31, %35, %28
%40 = phi double [ %30, %28 ], [ %34, %31 ], [ %38, %35 ]
%41 = fcmp olt double %40, 0.000000e+00
br i1 %41, label %42, label %44
42: ; preds = %39
%43 = fadd double %40, 6.000000e+00
br label %44
44: ; preds = %6, %39, %42
%45 = phi double [ %27, %42 ], [ %27, %39 ], [ 0.000000e+00, %6 ]
%46 = phi double [ %43, %42 ], [ %40, %39 ], [ 0.000000e+00, %6 ]
%47 = fmul double %46, 6.000000e+01
%48 = fptosi double %47 to i32
store i32 %48, i32* %3
store double %45, double* %4
store double %19, double* %5
ret void
}