void chr_set(unsigned char *buf, unsigned char x, unsigned char y,
             unsigned char val) {
  unsigned char bytes_per_line;
  unsigned char offset;
  unsigned char data;
  bytes_per_line = (((buf)[1] & 0x1f) + 7) >> 3;
  offset = y * bytes_per_line + (x >> 3) + 3;
  data = buf[offset];
  if (val == 0)
    data &= ~(1 << (x & 7));
  else
    data |= (1 << (x & 7));
  buf[offset] = data;
}


x86 assembly (clang, -O0):
<chr_set>:
push   %rbp
mov    %rsp,%rbp
mov    %cl,%al
mov    %dl,%cl
mov    %sil,%dl
mov    %rdi,-0x8(%rbp)
mov    %dl,-0x9(%rbp)
mov    %cl,-0xa(%rbp)
mov    %al,-0xb(%rbp)
mov    -0x8(%rbp),%rax
movzbl 0x1(%rax),%eax
and    $0x1f,%eax
add    $0x7,%eax
sar    $0x3,%eax
mov    %al,-0xc(%rbp)
movzbl -0xa(%rbp),%eax
movzbl -0xc(%rbp),%ecx
imul   %ecx,%eax
movzbl -0x9(%rbp),%ecx
sar    $0x3,%ecx
add    %ecx,%eax
add    $0x3,%eax
mov    %al,-0xd(%rbp)
mov    -0x8(%rbp),%rax
movzbl -0xd(%rbp),%ecx
mov    (%rax,%rcx,1),%al
mov    %al,-0xe(%rbp)
movzbl -0xb(%rbp),%eax
cmp    $0x0,%eax
jne    1182 <chr_set+0x82>
movzbl -0x9(%rbp),%ecx
and    $0x7,%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    %eax,%ecx
xor    $0xffffffff,%ecx
movzbl -0xe(%rbp),%eax
and    %ecx,%eax
mov    %al,-0xe(%rbp)
jmp    119b <chr_set+0x9b>
movzbl -0x9(%rbp),%ecx
and    $0x7,%ecx
mov    $0x1,%eax
shl    %cl,%eax
mov    %eax,%ecx
movzbl -0xe(%rbp),%eax
or     %ecx,%eax
mov    %al,-0xe(%rbp)
mov    -0xe(%rbp),%dl
mov    -0x8(%rbp),%rax
movzbl -0xd(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<chr_set>:
mov    %ecx,%r8d
mov    0x1(%rdi),%al
and    $0x1f,%al
add    $0x7,%al
shr    $0x3,%al
mul    %dl
mov    %esi,%ecx
mov    %esi,%edx
shr    $0x3,%dl
add    %al,%dl
add    $0x3,%dl
movzbl %dl,%r9d
mov    (%rdi,%r9,1),%r10b
and    $0x7,%cl
mov    $0x1,%al
shl    %cl,%al
mov    $0xfe,%dl
mov    %esi,%ecx
rol    %cl,%dl
and    %r10b,%dl
or     %r10b,%al
test   %r8d,%r8d
movzbl %dl,%ecx
movzbl %al,%eax
cmove  %ecx,%eax
mov    %al,(%rdi,%r9,1)
ret

LLVM IR (-O0):
define void @chr_set(i8* %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) {
%5 = alloca i8*
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8
%11 = alloca i8
store i8* %0, i8** %5
store i8 %1, i8* %6
store i8 %2, i8* %7
store i8 %3, i8* %8
%12 = load i8*, i8** %5
%13 = getelementptr inbounds i8, i8* %12, i64 1
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
%16 = and i32 %15, 31
%17 = add nsw i32 %16, 7
%18 = ashr i32 %17, 3
%19 = trunc i32 %18 to i8
store i8 %19, i8* %9
%20 = load i8, i8* %7
%21 = zext i8 %20 to i32
%22 = load i8, i8* %9
%23 = zext i8 %22 to i32
%24 = mul nsw i32 %21, %23
%25 = load i8, i8* %6
%26 = zext i8 %25 to i32
%27 = ashr i32 %26, 3
%28 = add nsw i32 %24, %27
%29 = add nsw i32 %28, 3
%30 = trunc i32 %29 to i8
store i8 %30, i8* %10
%31 = load i8*, i8** %5
%32 = load i8, i8* %10
%33 = zext i8 %32 to i64
%34 = getelementptr inbounds i8, i8* %31, i64 %33
%35 = load i8, i8* %34
store i8 %35, i8* %11
%36 = load i8, i8* %8
%37 = zext i8 %36 to i32
%38 = icmp eq i32 %37, 0
br i1 %38, label %39, label %49
39: ; preds = %4
%40 = load i8, i8* %6
%41 = zext i8 %40 to i32
%42 = and i32 %41, 7
%43 = shl i32 1, %42
%44 = xor i32 %43, -1
%45 = load i8, i8* %11
%46 = zext i8 %45 to i32
%47 = and i32 %46, %44
%48 = trunc i32 %47 to i8
store i8 %48, i8* %11
br label %58
49: ; preds = %4
%50 = load i8, i8* %6
%51 = zext i8 %50 to i32
%52 = and i32 %51, 7
%53 = shl i32 1, %52
%54 = load i8, i8* %11
%55 = zext i8 %54 to i32
%56 = or i32 %55, %53
%57 = trunc i32 %56 to i8
store i8 %57, i8* %11
br label %58
58: ; preds = %49, %39
%59 = load i8, i8* %11
%60 = load i8*, i8** %5
%61 = load i8, i8* %10
%62 = zext i8 %61 to i64
%63 = getelementptr inbounds i8, i8* %60, i64 %62
store i8 %59, i8* %63
ret void
}

LLVM IR (-O2):
define void @chr_set(i8* nocapture %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) {
%5 = getelementptr inbounds i8, i8* %0, i64 1
%6 = load i8, i8* %5
%7 = and i8 %6, 31
%8 = add nuw nsw i8 %7, 7
%9 = lshr i8 %8, 3
%10 = mul i8 %9, %2
%11 = lshr i8 %1, 3
%12 = add nuw nsw i8 %11, 3
%13 = add i8 %12, %10
%14 = zext i8 %13 to i64
%15 = getelementptr inbounds i8, i8* %0, i64 %14
%16 = load i8, i8* %15
%17 = icmp eq i8 %3, 0
%18 = and i8 %1, 7
%19 = shl nuw i8 1, %18
%20 = xor i8 %19, -1
%21 = and i8 %16, %20
%22 = or i8 %16, %19
%23 = select i1 %17, i8 %21, i8 %22
store i8 %23, i8* %15
ret void
}