unsigned char compareDouble(double left, double right, unsigned char op) {
  switch (op) {
  case 0x01:
    return (left < right);
  case 0x02:
    return (left <= right);
  case 0x03:
    return (left > right);
  case 0x04:
    return (left >= right);
  case 0x05:
    return (left == right);
  case 0x06:
    return (left != right);
  }
  return 0;
}


x86 assembly (clang, -O0):
<compareDouble>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %al,-0x19(%rbp)
movzbl -0x19(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x28(%rbp)
sub    $0x5,%eax
ja     11ec <compareDouble+0xec>
mov    -0x28(%rbp),%rax
lea    0xecb(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movsd  -0x10(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movsd  -0x10(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
setae  %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
setae  %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
setne  %al
setp   %cl
or     %cl,%al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x1(%rbp)
jmp    11f0 <compareDouble+0xf0>
movb   $0x0,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<compareDouble>:
add    $0xff,%dil
cmp    $0x5,%dil
ja     1126 <compareDouble+0x26>
movzbl %dil,%eax
lea    0xeeb(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
ucomisd %xmm0,%xmm1
seta   %al
ret
xor    %eax,%eax
ret
ucomisd %xmm0,%xmm1
setae  %al
ret
ucomisd %xmm1,%xmm0
seta   %al
ret
ucomisd %xmm1,%xmm0
setae  %al
ret
cmpeqsd %xmm1,%xmm0
jmp    114d <compareDouble+0x4d>
cmpneqsd %xmm1,%xmm0
movq   %xmm0,%rax
and    $0x1,%eax
ret

LLVM IR (-O0):
define zeroext i8 @compareDouble(double %0, double %1, i8 zeroext %2) {
%4 = alloca i8
%5 = alloca double
%6 = alloca double
%7 = alloca i8
store double %0, double* %5
store double %1, double* %6
store i8 %2, i8* %7
%8 = load i8, i8* %7
%9 = zext i8 %8 to i32
switch i32 %9, label %46 [
i32 1, label %10
i32 2, label %16
i32 3, label %22
i32 4, label %28
i32 5, label %34
i32 6, label %40
]
10: ; preds = %3
%11 = load double, double* %5
%12 = load double, double* %6
%13 = fcmp olt double %11, %12
%14 = zext i1 %13 to i32
%15 = trunc i32 %14 to i8
store i8 %15, i8* %4
br label %47
16: ; preds = %3
%17 = load double, double* %5
%18 = load double, double* %6
%19 = fcmp ole double %17, %18
%20 = zext i1 %19 to i32
%21 = trunc i32 %20 to i8
store i8 %21, i8* %4
br label %47
22: ; preds = %3
%23 = load double, double* %5
%24 = load double, double* %6
%25 = fcmp ogt double %23, %24
%26 = zext i1 %25 to i32
%27 = trunc i32 %26 to i8
store i8 %27, i8* %4
br label %47
28: ; preds = %3
%29 = load double, double* %5
%30 = load double, double* %6
%31 = fcmp oge double %29, %30
%32 = zext i1 %31 to i32
%33 = trunc i32 %32 to i8
store i8 %33, i8* %4
br label %47
34: ; preds = %3
%35 = load double, double* %5
%36 = load double, double* %6
%37 = fcmp oeq double %35, %36
%38 = zext i1 %37 to i32
%39 = trunc i32 %38 to i8
store i8 %39, i8* %4
br label %47
40: ; preds = %3
%41 = load double, double* %5
%42 = load double, double* %6
%43 = fcmp une double %41, %42
%44 = zext i1 %43 to i32
%45 = trunc i32 %44 to i8
store i8 %45, i8* %4
br label %47
46: ; preds = %3
store i8 0, i8* %4
br label %47
47: ; preds = %46, %40, %34, %28, %22, %16, %10
%48 = load i8, i8* %4
ret i8 %48
}

LLVM IR (-O2):
define zeroext i8 @compareDouble(double %0, double %1, i8 zeroext %2) {
switch i8 %2, label %16 [
i8 1, label %4
i8 2, label %6
i8 3, label %8
i8 4, label %10
i8 5, label %12
i8 6, label %14
]
4: ; preds = %3
%5 = fcmp olt double %0, %1
br label %16
6: ; preds = %3
%7 = fcmp ole double %0, %1
br label %16
8: ; preds = %3
%9 = fcmp ogt double %0, %1
br label %16
10: ; preds = %3
%11 = fcmp oge double %0, %1
br label %16
12: ; preds = %3
%13 = fcmp oeq double %0, %1
br label %16
14: ; preds = %3
%15 = fcmp une double %0, %1
br label %16
16: ; preds = %3, %14, %12, %10, %8, %6, %4
%17 = phi i1 [ %15, %14 ], [ %13, %12 ], [ %11, %10 ], [ %9, %8 ], [ %7, %6 ], [ %5, %4 ], [ false, %3 ]
%18 = zext i1 %17 to i8
ret i8 %18
}