char putb2sfac(char *a1, char *a2, int index, char val) {
  int k = index / 8;
  int R = 7 - index % 8;
  if (val == 'r') {
    a1[k] = 1 << R | a1[k];
    a2[k] = 0 << R | a2[k];
  } else if (val == 'p') {
    a1[k] = 0 << R | a1[k];
    a2[k] = 1 << R | a2[k];
  } else {
    a1[k] = 0 << R | a1[k];
    a2[k] = 0 << R | a2[k];
  }
}


x86 assembly (clang, -O0):
<putb2sfac>:
push   %rbp
mov    %rsp,%rbp
mov    %cl,%al
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %al,-0x1d(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %eax,-0x24(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    $0x7,%eax
sub    %edx,%eax
mov    %eax,-0x28(%rbp)
movsbl -0x1d(%rbp),%eax
cmp    $0x72,%eax
jne    1190 <putb2sfac+0x90>
mov    -0x28(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%ecx
xor    %eax,%eax
shl    %cl,%eax
mov    -0x18(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1232 <putb2sfac+0x132>
movsbl -0x1d(%rbp),%eax
cmp    $0x70,%eax
jne    11e9 <putb2sfac+0xe9>
mov    -0x28(%rbp),%ecx
xor    %eax,%eax
shl    %cl,%eax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    -0x18(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    122d <putb2sfac+0x12d>
mov    -0x28(%rbp),%ecx
xor    %eax,%eax
shl    %cl,%eax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%ecx
xor    %eax,%eax
shl    %cl,%eax
mov    -0x18(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1232 <putb2sfac+0x132>
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<putb2sfac>:
mov    %ecx,%eax
lea    0x7(%rdx),%ecx
test   %edx,%edx
cmovns %edx,%ecx
cmp    $0x72,%al
je     1115 <putb2sfac+0x15>
cmp    $0x70,%al
jne    112e <putb2sfac+0x2e>
mov    %rsi,%rdi
mov    %ecx,%eax
sar    $0x3,%eax
and    $0xfffffff8,%ecx
sub    %edx,%ecx
add    $0x7,%ecx
mov    $0x1,%edx
shl    %cl,%edx
cltq
or     %dl,(%rdi,%rax,1)
ret

LLVM IR (-O0):
define signext i8 @putb2sfac(i8* %0, i8* %1, i32 %2, i8 signext %3) {
%5 = alloca i8
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i8
%10 = alloca i32
%11 = alloca i32
store i8* %0, i8** %6
store i8* %1, i8** %7
store i32 %2, i32* %8
store i8 %3, i8* %9
%12 = load i32, i32* %8
%13 = sdiv i32 %12, 8
store i32 %13, i32* %10
%14 = load i32, i32* %8
%15 = srem i32 %14, 8
%16 = sub nsw i32 7, %15
store i32 %16, i32* %11
%17 = load i8, i8* %9
%18 = sext i8 %17 to i32
%19 = icmp eq i32 %18, 114
br i1 %19, label %20, label %49
20: ; preds = %4
%21 = load i32, i32* %11
%22 = shl i32 1, %21
%23 = load i8*, i8** %6
%24 = load i32, i32* %10
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds i8, i8* %23, i64 %25
%27 = load i8, i8* %26
%28 = sext i8 %27 to i32
%29 = or i32 %22, %28
%30 = trunc i32 %29 to i8
%31 = load i8*, i8** %6
%32 = load i32, i32* %10
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds i8, i8* %31, i64 %33
store i8 %30, i8* %34
%35 = load i32, i32* %11
%36 = shl i32 0, %35
%37 = load i8*, i8** %7
%38 = load i32, i32* %10
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i8, i8* %37, i64 %39
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = or i32 %36, %42
%44 = trunc i32 %43 to i8
%45 = load i8*, i8** %7
%46 = load i32, i32* %10
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds i8, i8* %45, i64 %47
store i8 %44, i8* %48
br label %112
49: ; preds = %4
%50 = load i8, i8* %9
%51 = sext i8 %50 to i32
%52 = icmp eq i32 %51, 112
br i1 %52, label %53, label %82
53: ; preds = %49
%54 = load i32, i32* %11
%55 = shl i32 0, %54
%56 = load i8*, i8** %6
%57 = load i32, i32* %10
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds i8, i8* %56, i64 %58
%60 = load i8, i8* %59
%61 = sext i8 %60 to i32
%62 = or i32 %55, %61
%63 = trunc i32 %62 to i8
%64 = load i8*, i8** %6
%65 = load i32, i32* %10
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds i8, i8* %64, i64 %66
store i8 %63, i8* %67
%68 = load i32, i32* %11
%69 = shl i32 1, %68
%70 = load i8*, i8** %7
%71 = load i32, i32* %10
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds i8, i8* %70, i64 %72
%74 = load i8, i8* %73
%75 = sext i8 %74 to i32
%76 = or i32 %69, %75
%77 = trunc i32 %76 to i8
%78 = load i8*, i8** %7
%79 = load i32, i32* %10
%80 = sext i32 %79 to i64
%81 = getelementptr inbounds i8, i8* %78, i64 %80
store i8 %77, i8* %81
br label %111
82: ; preds = %49
%83 = load i32, i32* %11
%84 = shl i32 0, %83
%85 = load i8*, i8** %6
%86 = load i32, i32* %10
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds i8, i8* %85, i64 %87
%89 = load i8, i8* %88
%90 = sext i8 %89 to i32
%91 = or i32 %84, %90
%92 = trunc i32 %91 to i8
%93 = load i8*, i8** %6
%94 = load i32, i32* %10
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds i8, i8* %93, i64 %95
store i8 %92, i8* %96
%97 = load i32, i32* %11
%98 = shl i32 0, %97
%99 = load i8*, i8** %7
%100 = load i32, i32* %10
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds i8, i8* %99, i64 %101
%103 = load i8, i8* %102
%104 = sext i8 %103 to i32
%105 = or i32 %98, %104
%106 = trunc i32 %105 to i8
%107 = load i8*, i8** %7
%108 = load i32, i32* %10
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds i8, i8* %107, i64 %109
store i8 %106, i8* %110
br label %111
111: ; preds = %82, %53
br label %112
112: ; preds = %111, %20
%113 = load i8, i8* %5
ret i8 %113
}

LLVM IR (-O2):
define signext i8 @putb2sfac(i8* nocapture %0, i8* nocapture %1, i32 %2, i8 signext %3) {
%5 = sdiv i32 %2, 8
%6 = srem i32 %2, 8
%7 = sub nsw i32 7, %6
switch i8 %3, label %17 [
i8 114, label %9
i8 112, label %8
]
8: ; preds = %4
br label %9
9: ; preds = %4, %8
%10 = phi i8* [ %1, %8 ], [ %0, %4 ]
%11 = sext i32 %5 to i64
%12 = getelementptr inbounds i8, i8* %10, i64 %11
%13 = shl nuw nsw i32 1, %7
%14 = load i8, i8* %12
%15 = trunc i32 %13 to i8
%16 = or i8 %14, %15
store i8 %16, i8* %12
br label %17
17: ; preds = %9, %4
ret i8 undef
}