int xrdp_painter_rop(int rop, int src, int dst) {
  switch (rop & 0x0f) {
  case 0x0:
    return 0;
  case 0x1:
    return ~(src | dst);
  case 0x2:
    return (~src) & dst;
  case 0x3:
    return ~src;
  case 0x4:
    return src & (~dst);
  case 0x5:
    return ~(dst);
  case 0x6:
    return src ^ dst;
  case 0x7:
    return ~(src & dst);
  case 0x8:
    return src & dst;
  case 0x9:
    return ~(src) ^ dst;
  case 0xa:
    return dst;
  case 0xb:
    return (~src) | dst;
  case 0xc:
    return src;
  case 0xd:
    return src | (~dst);
  case 0xe:
    return src | dst;
  case 0xf:
    return ~0;
  }
  return dst;
}


x86 assembly (clang, -O0):
<xrdp_painter_rop>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x8(%rbp),%eax
and    $0xf,%eax
mov    %rax,-0x18(%rbp)
sub    $0xf,%eax
ja     1223 <xrdp_painter_rop+0x123>
mov    -0x18(%rbp),%rax
lea    0xed5(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movl   $0x0,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
or     -0x10(%rbp),%eax
xor    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
xor    $0xffffffff,%eax
and    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
xor    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
mov    -0x10(%rbp),%ecx
xor    $0xffffffff,%ecx
and    %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0x10(%rbp),%eax
xor    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
xor    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
and    -0x10(%rbp),%eax
xor    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
and    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
xor    $0xffffffff,%eax
xor    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
xor    $0xffffffff,%eax
or     -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
mov    -0x10(%rbp),%ecx
xor    $0xffffffff,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0xc(%rbp),%eax
or     -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
movl   $0xffffffff,-0x4(%rbp)
jmp    1229 <xrdp_painter_rop+0x129>
mov    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<xrdp_painter_rop>:
mov    %edi,%eax
and    $0xf,%eax
lea    0xef4(%rip),%rcx
movslq (%rcx,%rax,4),%rdi
add    %rcx,%rdi
jmp    *%rdi
or     %esi,%edx
jmp    112e <xrdp_painter_rop+0x2e>
not    %esi
and    %edx,%esi
mov    %esi,%eax
ret
not    %edx
and    %esi,%edx
mov    %edx,%eax
ret
xor    %esi,%edx
mov    %edx,%eax
ret
and    %esi,%edx
not    %edx
mov    %edx,%eax
ret
xor    %edx,%esi
not    %esi
mov    %esi,%eax
ret
not    %esi
or     %edx,%esi
mov    %esi,%eax
ret
not    %edx
or     %esi,%edx
mov    %edx,%eax
ret
mov    $0xffffffff,%eax
ret

LLVM IR (-O0):
define i32 @xrdp_painter_rop(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32 %0, i32* %5
store i32 %1, i32* %6
store i32 %2, i32* %7
%8 = load i32, i32* %5
%9 = and i32 %8, 15
switch i32 %9, label %69 [
i32 0, label %10
i32 1, label %11
i32 2, label %16
i32 3, label %21
i32 4, label %24
i32 5, label %29
i32 6, label %32
i32 7, label %36
i32 8, label %41
i32 9, label %45
i32 10, label %50
i32 11, label %52
i32 12, label %57
i32 13, label %59
i32 14, label %64
i32 15, label %68
]
10: ; preds = %3
store i32 0, i32* %4
br label %71
11: ; preds = %3
%12 = load i32, i32* %6
%13 = load i32, i32* %7
%14 = or i32 %12, %13
%15 = xor i32 %14, -1
store i32 %15, i32* %4
br label %71
16: ; preds = %3
%17 = load i32, i32* %6
%18 = xor i32 %17, -1
%19 = load i32, i32* %7
%20 = and i32 %18, %19
store i32 %20, i32* %4
br label %71
21: ; preds = %3
%22 = load i32, i32* %6
%23 = xor i32 %22, -1
store i32 %23, i32* %4
br label %71
24: ; preds = %3
%25 = load i32, i32* %6
%26 = load i32, i32* %7
%27 = xor i32 %26, -1
%28 = and i32 %25, %27
store i32 %28, i32* %4
br label %71
29: ; preds = %3
%30 = load i32, i32* %7
%31 = xor i32 %30, -1
store i32 %31, i32* %4
br label %71
32: ; preds = %3
%33 = load i32, i32* %6
%34 = load i32, i32* %7
%35 = xor i32 %33, %34
store i32 %35, i32* %4
br label %71
36: ; preds = %3
%37 = load i32, i32* %6
%38 = load i32, i32* %7
%39 = and i32 %37, %38
%40 = xor i32 %39, -1
store i32 %40, i32* %4
br label %71
41: ; preds = %3
%42 = load i32, i32* %6
%43 = load i32, i32* %7
%44 = and i32 %42, %43
store i32 %44, i32* %4
br label %71
45: ; preds = %3
%46 = load i32, i32* %6
%47 = xor i32 %46, -1
%48 = load i32, i32* %7
%49 = xor i32 %47, %48
store i32 %49, i32* %4
br label %71
50: ; preds = %3
%51 = load i32, i32* %7
store i32 %51, i32* %4
br label %71
52: ; preds = %3
%53 = load i32, i32* %6
%54 = xor i32 %53, -1
%55 = load i32, i32* %7
%56 = or i32 %54, %55
store i32 %56, i32* %4
br label %71
57: ; preds = %3
%58 = load i32, i32* %6
store i32 %58, i32* %4
br label %71
59: ; preds = %3
%60 = load i32, i32* %6
%61 = load i32, i32* %7
%62 = xor i32 %61, -1
%63 = or i32 %60, %62
store i32 %63, i32* %4
br label %71
64: ; preds = %3
%65 = load i32, i32* %6
%66 = load i32, i32* %7
%67 = or i32 %65, %66
store i32 %67, i32* %4
br label %71
68: ; preds = %3
store i32 -1, i32* %4
br label %71
69: ; preds = %3
%70 = load i32, i32* %7
store i32 %70, i32* %4
br label %71
71: ; preds = %69, %68, %64, %59, %57, %52, %50, %45, %41, %36, %32, %29, %24, %21, %16, %11, %10
%72 = load i32, i32* %4
ret i32 %72
}

LLVM IR (-O2):
define i32 @xrdp_painter_rop(i32 %0, i32 %1, i32 %2) {
%4 = and i32 %0, 15
switch i32 %4, label %39 [
i32 0, label %40
i32 1, label %5
i32 2, label %8
i32 3, label %11
i32 4, label %13
i32 5, label %16
i32 6, label %18
i32 7, label %20
i32 8, label %23
i32 9, label %25
i32 10, label %28
i32 11, label %29
i32 12, label %32
i32 13, label %33
i32 14, label %36
i32 15, label %38
]
5: ; preds = %3
%6 = or i32 %2, %1
%7 = xor i32 %6, -1
br label %40
8: ; preds = %3
%9 = xor i32 %1, -1
%10 = and i32 %9, %2
br label %40
11: ; preds = %3
%12 = xor i32 %1, -1
br label %40
13: ; preds = %3
%14 = xor i32 %2, -1
%15 = and i32 %14, %1
br label %40
16: ; preds = %3
%17 = xor i32 %2, -1
br label %40
18: ; preds = %3
%19 = xor i32 %2, %1
br label %40
20: ; preds = %3
%21 = and i32 %2, %1
%22 = xor i32 %21, -1
br label %40
23: ; preds = %3
%24 = and i32 %2, %1
br label %40
25: ; preds = %3
%26 = xor i32 %1, %2
%27 = xor i32 %26, -1
br label %40
28: ; preds = %3
br label %40
29: ; preds = %3
%30 = xor i32 %1, -1
%31 = or i32 %30, %2
br label %40
32: ; preds = %3
br label %40
33: ; preds = %3
%34 = xor i32 %2, -1
%35 = or i32 %34, %1
br label %40
36: ; preds = %3
%37 = or i32 %2, %1
br label %40
38: ; preds = %3
br label %40
39: ; preds = %3
unreachable
40: ; preds = %3, %38, %36, %33, %32, %29, %28, %25, %23, %20, %18, %16, %13, %11, %8, %5
%41 = phi i32 [ -1, %38 ], [ %37, %36 ], [ %35, %33 ], [ %1, %32 ], [ %31, %29 ], [ %2, %28 ], [ %27, %25 ], [ %24, %23 ], [ %22, %20 ], [ %19, %18 ], [ %17, %16 ], [ %15, %13 ], [ %12, %11 ], [ %10, %8 ], [ %7, %5 ], [ %4, %3 ]
ret i32 %41
}