int nv01_pgraph_dither_10to5(int val, int x, int y, int isg) {
  int step = val >> 2 & 7;
  static const int tab1[4][4] = {
      {0, 1, 1, 0},
      {0, 0, 1, 0},
      {0, 0, 1, 1},
      {1, 1, 1, 1},
  };
  int w = (x ^ y) >> 1 & 1;
  ;
  int z = tab1[y >> 2 & 3][x >> 2 & 3] ^ isg;
  if (step & 1)
    z ^= w;
  int tx = x & 1;
  int ty = y & 1;
  int d;
  switch (step) {
  case 0:
    d = 0;
    break;
  case 1:
    d = !tx && !ty && z;
    break;
  case 2:
    d = !(tx ^ ty) && (tx ^ z);
    break;
  case 3:
    d = !(tx ^ ty) && (!tx || z);
    break;
  case 4:
    d = !(tx ^ ty);
    break;
  case 5:
    d = !(tx ^ ty) || (tx && !ty && z);
    break;
  case 6:
    d = !(tx ^ ty) || (ty ^ z);
    break;
  case 7:
    d = tx || !ty || z;
    break;
  default:
    d = 0;
    break;
  }
  val += d << 5;
  if (val > 0x3ff)
    val = 0x3ff;
  return val >> 5;
}


x86 assembly (clang, -O0):
<nv01_pgraph_dither_10to5>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x2,%eax
and    $0x7,%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%eax
xor    -0xc(%rbp),%eax
sar    $0x1,%eax
and    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
sar    $0x2,%eax
and    $0x3,%eax
movslq %eax,%rcx
lea    0xee2(%rip),%rax
shl    $0x4,%rcx
add    %rcx,%rax
mov    -0x8(%rbp),%ecx
sar    $0x2,%ecx
and    $0x3,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
xor    -0x10(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     1172 <nv01_pgraph_dither_10to5+0x72>
mov    -0x18(%rbp),%eax
xor    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%eax
and    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
and    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x14(%rbp),%eax
mov    %rax,-0x30(%rbp)
sub    $0x7,%rax
ja     133b <nv01_pgraph_dither_10to5+0x23b>
mov    -0x30(%rbp),%rax
lea    0xe60(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movl   $0x0,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
xor    %eax,%eax
cmpl   $0x0,-0x20(%rbp)
mov    %al,-0x31(%rbp)
jne    11dd <nv01_pgraph_dither_10to5+0xdd>
xor    %eax,%eax
cmpl   $0x0,-0x24(%rbp)
mov    %al,-0x31(%rbp)
jne    11dd <nv01_pgraph_dither_10to5+0xdd>
cmpl   $0x0,-0x1c(%rbp)
setne  %al
mov    %al,-0x31(%rbp)
mov    -0x31(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    -0x20(%rbp),%ecx
xor    -0x24(%rbp),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x32(%rbp)
jne    1210 <nv01_pgraph_dither_10to5+0x110>
mov    -0x20(%rbp),%eax
xor    -0x1c(%rbp),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x32(%rbp)
mov    -0x32(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    -0x20(%rbp),%ecx
xor    -0x24(%rbp),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x33(%rbp)
jne    1253 <nv01_pgraph_dither_10to5+0x153>
mov    $0x1,%al
cmpl   $0x0,-0x20(%rbp)
mov    %al,-0x34(%rbp)
je     124d <nv01_pgraph_dither_10to5+0x14d>
cmpl   $0x0,-0x1c(%rbp)
setne  %al
mov    %al,-0x34(%rbp)
mov    -0x34(%rbp),%al
mov    %al,-0x33(%rbp)
mov    -0x33(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    -0x20(%rbp),%eax
xor    -0x24(%rbp),%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    -0x20(%rbp),%ecx
xor    -0x24(%rbp),%ecx
mov    $0x1,%al
cmp    $0x0,%ecx
mov    %al,-0x35(%rbp)
je     12c0 <nv01_pgraph_dither_10to5+0x1c0>
xor    %eax,%eax
cmpl   $0x0,-0x20(%rbp)
mov    %al,-0x36(%rbp)
je     12ba <nv01_pgraph_dither_10to5+0x1ba>
xor    %eax,%eax
cmpl   $0x0,-0x24(%rbp)
mov    %al,-0x36(%rbp)
jne    12ba <nv01_pgraph_dither_10to5+0x1ba>
cmpl   $0x0,-0x1c(%rbp)
setne  %al
mov    %al,-0x36(%rbp)
mov    -0x36(%rbp),%al
mov    %al,-0x35(%rbp)
mov    -0x35(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    -0x20(%rbp),%ecx
xor    -0x24(%rbp),%ecx
mov    $0x1,%al
cmp    $0x0,%ecx
mov    %al,-0x37(%rbp)
je     12f3 <nv01_pgraph_dither_10to5+0x1f3>
mov    -0x24(%rbp),%eax
xor    -0x1c(%rbp),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x37(%rbp)
mov    -0x37(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
mov    $0x1,%al
cmpl   $0x0,-0x20(%rbp)
mov    %al,-0x38(%rbp)
jne    132b <nv01_pgraph_dither_10to5+0x22b>
mov    $0x1,%al
cmpl   $0x0,-0x24(%rbp)
mov    %al,-0x38(%rbp)
je     132b <nv01_pgraph_dither_10to5+0x22b>
cmpl   $0x0,-0x1c(%rbp)
setne  %al
mov    %al,-0x38(%rbp)
mov    -0x38(%rbp),%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x28(%rbp)
jmp    1342 <nv01_pgraph_dither_10to5+0x242>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
shl    $0x5,%eax
add    -0x4(%rbp),%eax
mov    %eax,-0x4(%rbp)
cmpl   $0x3ff,-0x4(%rbp)
jle    1362 <nv01_pgraph_dither_10to5+0x262>
movl   $0x3ff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x5,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<nv01_pgraph_dither_10to5>:
mov    %edi,%r9d
shr    $0x2,%r9d
mov    %r9d,%r8d
and    $0x7,%r8d
add    $0xffffffff,%r8d
cmp    $0x6,%r8d
ja     11cf <nv01_pgraph_dither_10to5+0xcf>
mov    %edx,%eax
shr    $0x2,%eax
and    $0x3,%eax
mov    %esi,%r10d
shr    $0x2,%r10d
and    $0x3,%r10d
shl    $0x4,%rax
lea    0xee6(%rip),%r11
add    %rax,%r11
mov    %edx,%eax
xor    %esi,%eax
shr    %eax
and    %r9d,%eax
and    $0x1,%eax
xor    %ecx,%eax
xor    (%r11,%r10,4),%eax
mov    %esi,%r9d
and    $0x1,%r9d
mov    %edx,%r10d
and    $0x1,%r10d
lea    0xe9c(%rip),%r11
movslq (%r11,%r8,4),%rcx
add    %r11,%rcx
jmp    *%rcx
or     %esi,%edx
test   $0x1,%dl
sete   %cl
test   %eax,%eax
jmp    1182 <nv01_pgraph_dither_10to5+0x82>
cmp    %r10d,%r9d
sete   %cl
cmp    %eax,%r9d
setne  %al
jmp    119a <nv01_pgraph_dither_10to5+0x9a>
cmp    %r10d,%r9d
sete   %cl
test   %r9d,%r9d
sete   %dl
test   %eax,%eax
setne  %al
or     %dl,%al
and    %cl,%al
movzbl %al,%ecx
jmp    11fe <nv01_pgraph_dither_10to5+0xfe>
xor    %r10d,%r9d
xor    $0x1,%r9d
mov    %r9d,%ecx
jmp    11fe <nv01_pgraph_dither_10to5+0xfe>
mov    $0x1,%ecx
cmp    %r10d,%r9d
je     11fe <nv01_pgraph_dither_10to5+0xfe>
test   %r9d,%r9d
je     11cf <nv01_pgraph_dither_10to5+0xcf>
mov    $0x0,%ecx
test   %r10d,%r10d
jne    11fe <nv01_pgraph_dither_10to5+0xfe>
xor    %ecx,%ecx
test   %eax,%eax
setne  %cl
jmp    11fe <nv01_pgraph_dither_10to5+0xfe>
xor    %ecx,%ecx
jmp    11fe <nv01_pgraph_dither_10to5+0xfe>
cmp    %r10d,%r9d
sete   %cl
cmp    %eax,%r10d
setne  %al
or     %cl,%al
movzbl %al,%ecx
jmp    11fe <nv01_pgraph_dither_10to5+0xfe>
test   %r9d,%r9d
setne  %cl
test   %r10d,%r10d
sete   %dl
test   %eax,%eax
setne  %al
or     %cl,%dl
or     %al,%dl
movzbl %dl,%ecx
shl    $0x5,%ecx
add    %edi,%ecx
cmp    $0x3ff,%ecx
mov    $0x3ff,%eax
cmovl  %ecx,%eax
sar    $0x5,%eax
ret

LLVM IR (-O0):
@nv01_pgraph_dither_10to5.tab1 = internal constant [4 x [4 x i32]] [[4 x i32] [i32 0, i32 1, i32 1, i32 0], [4 x i32] [i32 0, i32 0, i32 1, i32 0], [4 x i32] [i32 0, i32 0, i32 1, i32 1], [4 x i32] [i32 1, i32 1, i32 1, i32 1]]
define i32 @nv01_pgraph_dither_10to5(i32 %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
store i32 %0, i32* %5
store i32 %1, i32* %6
store i32 %2, i32* %7
store i32 %3, i32* %8
%15 = load i32, i32* %5
%16 = ashr i32 %15, 2
%17 = and i32 %16, 7
store i32 %17, i32* %9
%18 = load i32, i32* %6
%19 = load i32, i32* %7
%20 = xor i32 %18, %19
%21 = ashr i32 %20, 1
%22 = and i32 %21, 1
store i32 %22, i32* %10
%23 = load i32, i32* %7
%24 = ashr i32 %23, 2
%25 = and i32 %24, 3
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds [4 x [4 x i32]], [4 x [4 x i32]]* @nv01_pgraph_dither_10to5.tab1, i64 0, i64 %26
%28 = load i32, i32* %6
%29 = ashr i32 %28, 2
%30 = and i32 %29, 3
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds [4 x i32], [4 x i32]* %27, i64 0, i64 %31
%33 = load i32, i32* %32
%34 = load i32, i32* %8
%35 = xor i32 %33, %34
store i32 %35, i32* %11
%36 = load i32, i32* %9
%37 = and i32 %36, 1
%38 = icmp ne i32 %37, 0
br i1 %38, label %39, label %43
39: ; preds = %4
%40 = load i32, i32* %10
%41 = load i32, i32* %11
%42 = xor i32 %41, %40
store i32 %42, i32* %11
br label %43
43: ; preds = %39, %4
%44 = load i32, i32* %6
%45 = and i32 %44, 1
store i32 %45, i32* %12
%46 = load i32, i32* %7
%47 = and i32 %46, 1
store i32 %47, i32* %13
%48 = load i32, i32* %9
switch i32 %48, label %142 [
i32 0, label %49
i32 1, label %50
i32 2, label %62
i32 3, label %75
i32 4, label %91
i32 5, label %98
i32 6, label %117
i32 7, label %130
]
49: ; preds = %43
store i32 0, i32* %14
br label %143
50: ; preds = %43
%51 = load i32, i32* %12
%52 = icmp ne i32 %51, 0
br i1 %52, label %59, label %53
53: ; preds = %50
%54 = load i32, i32* %13
%55 = icmp ne i32 %54, 0
br i1 %55, label %59, label %56
56: ; preds = %53
%57 = load i32, i32* %11
%58 = icmp ne i32 %57, 0
br label %59
59: ; preds = %56, %53, %50
%60 = phi i1 [ false, %53 ], [ false, %50 ], [ %58, %56 ]
%61 = zext i1 %60 to i32
store i32 %61, i32* %14
br label %143
62: ; preds = %43
%63 = load i32, i32* %12
%64 = load i32, i32* %13
%65 = xor i32 %63, %64
%66 = icmp ne i32 %65, 0
br i1 %66, label %72, label %67
67: ; preds = %62
%68 = load i32, i32* %12
%69 = load i32, i32* %11
%70 = xor i32 %68, %69
%71 = icmp ne i32 %70, 0
br label %72
72: ; preds = %67, %62
%73 = phi i1 [ false, %62 ], [ %71, %67 ]
%74 = zext i1 %73 to i32
store i32 %74, i32* %14
br label %143
75: ; preds = %43
%76 = load i32, i32* %12
%77 = load i32, i32* %13
%78 = xor i32 %76, %77
%79 = icmp ne i32 %78, 0
br i1 %79, label %88, label %80
80: ; preds = %75
%81 = load i32, i32* %12
%82 = icmp ne i32 %81, 0
br i1 %82, label %83, label %86
83: ; preds = %80
%84 = load i32, i32* %11
%85 = icmp ne i32 %84, 0
br label %86
86: ; preds = %83, %80
%87 = phi i1 [ true, %80 ], [ %85, %83 ]
br label %88
88: ; preds = %86, %75
%89 = phi i1 [ false, %75 ], [ %87, %86 ]
%90 = zext i1 %89 to i32
store i32 %90, i32* %14
br label %143
91: ; preds = %43
%92 = load i32, i32* %12
%93 = load i32, i32* %13
%94 = xor i32 %92, %93
%95 = icmp ne i32 %94, 0
%96 = xor i1 %95, true
%97 = zext i1 %96 to i32
store i32 %97, i32* %14
br label %143
98: ; preds = %43
%99 = load i32, i32* %12
%100 = load i32, i32* %13
%101 = xor i32 %99, %100
%102 = icmp ne i32 %101, 0
br i1 %102, label %103, label %114
103: ; preds = %98
%104 = load i32, i32* %12
%105 = icmp ne i32 %104, 0
br i1 %105, label %106, label %112
106: ; preds = %103
%107 = load i32, i32* %13
%108 = icmp ne i32 %107, 0
br i1 %108, label %112, label %109
109: ; preds = %106
%110 = load i32, i32* %11
%111 = icmp ne i32 %110, 0
br label %112
112: ; preds = %109, %106, %103
%113 = phi i1 [ false, %106 ], [ false, %103 ], [ %111, %109 ]
br label %114
114: ; preds = %112, %98
%115 = phi i1 [ true, %98 ], [ %113, %112 ]
%116 = zext i1 %115 to i32
store i32 %116, i32* %14
br label %143
117: ; preds = %43
%118 = load i32, i32* %12
%119 = load i32, i32* %13
%120 = xor i32 %118, %119
%121 = icmp ne i32 %120, 0
br i1 %121, label %122, label %127
122: ; preds = %117
%123 = load i32, i32* %13
%124 = load i32, i32* %11
%125 = xor i32 %123, %124
%126 = icmp ne i32 %125, 0
br label %127
127: ; preds = %122, %117
%128 = phi i1 [ true, %117 ], [ %126, %122 ]
%129 = zext i1 %128 to i32
store i32 %129, i32* %14
br label %143
130: ; preds = %43
%131 = load i32, i32* %12
%132 = icmp ne i32 %131, 0
br i1 %132, label %139, label %133
133: ; preds = %130
%134 = load i32, i32* %13
%135 = icmp ne i32 %134, 0
br i1 %135, label %136, label %139
136: ; preds = %133
%137 = load i32, i32* %11
%138 = icmp ne i32 %137, 0
br label %139
139: ; preds = %136, %133, %130
%140 = phi i1 [ true, %133 ], [ true, %130 ], [ %138, %136 ]
%141 = zext i1 %140 to i32
store i32 %141, i32* %14
br label %143
142: ; preds = %43
store i32 0, i32* %14
br label %143
143: ; preds = %142, %139, %127, %114, %91, %88, %72, %59, %49
%144 = load i32, i32* %14
%145 = shl i32 %144, 5
%146 = load i32, i32* %5
%147 = add nsw i32 %146, %145
store i32 %147, i32* %5
%148 = load i32, i32* %5
%149 = icmp sgt i32 %148, 1023
br i1 %149, label %150, label %151
150: ; preds = %143
store i32 1023, i32* %5
br label %151
151: ; preds = %150, %143
%152 = load i32, i32* %5
%153 = ashr i32 %152, 5
ret i32 %153
}

LLVM IR (-O2):
@nv01_pgraph_dither_10to5.tab1 = internal unnamed_addr constant [4 x [4 x i32]] [[4 x i32] [i32 0, i32 1, i32 1, i32 0], [4 x i32] [i32 0, i32 0, i32 1, i32 0], [4 x i32] [i32 0, i32 0, i32 1, i32 1], [4 x i32] [i32 1, i32 1, i32 1, i32 1]]
define i32 @nv01_pgraph_dither_10to5(i32 %0, i32 %1, i32 %2, i32 %3) {
%5 = lshr i32 %0, 2
%6 = and i32 %5, 7
%7 = lshr i32 %2, 2
%8 = and i32 %7, 3
%9 = zext i32 %8 to i64
%10 = lshr i32 %1, 2
%11 = and i32 %10, 3
%12 = zext i32 %11 to i64
%13 = getelementptr inbounds [4 x [4 x i32]], [4 x [4 x i32]]* @nv01_pgraph_dither_10to5.tab1, i64 0, i64 %9, i64 %12
%14 = load i32, i32* %13
%15 = and i32 %0, 4
%16 = icmp eq i32 %15, 0
%17 = xor i32 %2, %1
%18 = lshr i32 %17, 1
%19 = and i32 %18, 1
%20 = select i1 %16, i32 0, i32 %19
%21 = xor i32 %20, %3
%22 = xor i32 %21, %14
%23 = and i32 %1, 1
%24 = and i32 %2, 1
switch i32 %6, label %68 [
i32 7, label %61
i32 1, label %25
i32 2, label %32
i32 3, label %37
i32 4, label %44
i32 5, label %47
i32 6, label %56
]
25: ; preds = %4
%26 = or i32 %2, %1
%27 = and i32 %26, 1
%28 = icmp eq i32 %27, 0
%29 = icmp ne i32 %22, 0
%30 = select i1 %28, i1 %29, i1 false
%31 = zext i1 %30 to i32
br label %68
32: ; preds = %4
%33 = icmp eq i32 %23, %24
%34 = icmp ne i32 %23, %22
%35 = select i1 %33, i1 %34, i1 false
%36 = zext i1 %35 to i32
br label %68
37: ; preds = %4
%38 = icmp eq i32 %23, %24
%39 = icmp eq i32 %23, 0
%40 = icmp ne i32 %22, 0
%41 = select i1 %39, i1 true, i1 %40
%42 = select i1 %38, i1 %41, i1 false
%43 = zext i1 %42 to i32
br label %68
44: ; preds = %4
%45 = xor i32 %23, %24
%46 = xor i32 %45, 1
br label %68
47: ; preds = %4
%48 = icmp eq i32 %23, %24
br i1 %48, label %68, label %49
49: ; preds = %47
%50 = icmp eq i32 %23, 0
%51 = icmp ne i32 %24, 0
%52 = or i1 %50, %51
br i1 %52, label %68, label %53
53: ; preds = %49
%54 = icmp ne i32 %22, 0
%55 = zext i1 %54 to i32
br label %68
56: ; preds = %4
%57 = icmp eq i32 %23, %24
%58 = icmp ne i32 %24, %22
%59 = select i1 %57, i1 true, i1 %58
%60 = zext i1 %59 to i32
br label %68
61: ; preds = %4
%62 = icmp ne i32 %23, 0
%63 = icmp eq i32 %24, 0
%64 = icmp ne i32 %22, 0
%65 = or i1 %62, %63
%66 = select i1 %65, i1 true, i1 %64
%67 = zext i1 %66 to i32
br label %68
68: ; preds = %4, %47, %53, %49, %61, %56, %44, %37, %32, %25
%69 = phi i32 [ %67, %61 ], [ %60, %56 ], [ %46, %44 ], [ %43, %37 ], [ %36, %32 ], [ %31, %25 ], [ 1, %47 ], [ 0, %49 ], [ %55, %53 ], [ 0, %4 ]
%70 = shl i32 %69, 5
%71 = add nsw i32 %70, %0
%72 = icmp slt i32 %71, 1023
%73 = select i1 %72, i32 %71, i32 1023
%74 = ashr i32 %73, 5
ret i32 %74
}