void putfont8(char *vram, int xsize, int x, int y, char c, char *font) {
  int i, temp, counter;
  char d;
  for (i = 0; i < 16; i++) {
    d = font[i];
    temp = 0x80;
    counter = 0;
    while (temp > 0) {
      if ((d & temp) != 0)
        vram[(y + i) * xsize + x + counter] = c;
      temp = temp >> 1;
      counter++;
    }
  }
}


x86 assembly (clang, -O0):
<putfont8>:
push   %rbp
mov    %rsp,%rbp
mov    %r8b,%al
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %al,-0x15(%rbp)
mov    %r9,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
cmpl   $0x10,-0x24(%rbp)
jge    11a9 <putfont8+0xa9>
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x2d(%rbp)
movl   $0x80,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
cmpl   $0x0,-0x28(%rbp)
jle    1196 <putfont8+0x96>
movsbl -0x2d(%rbp),%eax
and    -0x28(%rbp),%eax
cmp    $0x0,%eax
je     117f <putfont8+0x7f>
mov    -0x15(%rbp),%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
imul   -0xc(%rbp),%ecx
add    -0x10(%rbp),%ecx
add    -0x2c(%rbp),%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1148 <putfont8+0x48>
jmp    119b <putfont8+0x9b>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1122 <putfont8+0x22>
pop    %rbp
ret

x86 assembly (clang, -O2):
<putfont8>:
movslq %ecx,%rcx
movslq %esi,%rax
movslq %edx,%rdx
imul   %rax,%rcx
add    %rdx,%rcx
add    %rdi,%rcx
add    $0x7,%rcx
xor    %edx,%edx
jmp    1131 <putfont8+0x31>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rdx
add    %rax,%rcx
cmp    $0x10,%rdx
je     11c2 <putfont8+0xc2>
movzbl (%r9,%rdx,1),%esi
test   $0x80,%sil
jne    1170 <putfont8+0x70>
test   $0x40,%sil
jne    117a <putfont8+0x7a>
test   $0x20,%sil
jne    1184 <putfont8+0x84>
test   $0x10,%sil
jne    118e <putfont8+0x8e>
test   $0x8,%sil
jne    1198 <putfont8+0x98>
test   $0x4,%sil
jne    11a2 <putfont8+0xa2>
test   $0x2,%sil
jne    11ac <putfont8+0xac>
test   $0x1,%sil
je     1120 <putfont8+0x20>
jmp    11ba <putfont8+0xba>
nopl   0x0(%rax,%rax,1)
mov    %r8b,-0x7(%rcx)
test   $0x40,%sil
je     1142 <putfont8+0x42>
mov    %r8b,-0x6(%rcx)
test   $0x20,%sil
je     1148 <putfont8+0x48>
mov    %r8b,-0x5(%rcx)
test   $0x10,%sil
je     114e <putfont8+0x4e>
mov    %r8b,-0x4(%rcx)
test   $0x8,%sil
je     1154 <putfont8+0x54>
mov    %r8b,-0x3(%rcx)
test   $0x4,%sil
je     115a <putfont8+0x5a>
mov    %r8b,-0x2(%rcx)
test   $0x2,%sil
je     1160 <putfont8+0x60>
mov    %r8b,-0x1(%rcx)
test   $0x1,%sil
je     1120 <putfont8+0x20>
mov    %r8b,(%rcx)
jmp    1120 <putfont8+0x20>
ret

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

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