#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct raster {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ drawline(struct raster *, int, int, int, int, int, int, int);
char *strchr(char *, char);
void drawcharseg(struct raster *ra, int x, int y, char *s, int size, int r,
                 int g, int b) {
  int segments[] = {0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0,
                    2, 0, 2, 2, 2, 2, 2, 4, 2, 4, 1, 4, 1, 4, 0, 4,
                    0, 4, 1, 2, 0, 2, 1, 2, 0, 0, 1, 2, 1, 0, 1, 2,
                    2, 0, 1, 2, 2, 2, 1, 2, 2, 4, 1, 2, 1, 4, 1, 2};
  char *sym = "0123456789abcdef";
  while (*s) {
    char *p;
    int off, x1, x2, y1, y2;
    p = strchr(sym, *s);
    if (!p)
      continue;
    off = p - sym;
    x1 = segments[off * 4] * size;
    y1 = segments[off * 4 + 1] * size;
    x2 = segments[off * 4 + 2] * size;
    y2 = segments[off * 4 + 3] * size;
    drawline(ra, x + x1, y + y1, x + x2, y + y2, r, g, b);
    s++;
  }
}


x86 assembly (clang, -O0):
<drawcharseg>:
push   %rbp
mov    %rsp,%rbp
sub    $0x160,%rsp
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
mov    %r9d,-0x20(%rbp)
lea    -0x120(%rbp),%rdi
lea    0xe9b(%rip),%rsi
mov    $0x100,%edx
call   1040 <memcpy@plt>
lea    0xf8a(%rip),%rax
mov    %rax,-0x128(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     129a <drawcharseg+0x16a>
mov    -0x128(%rbp),%rdi
mov    -0x18(%rbp),%rax
movsbl (%rax),%esi
call   1030 <strchr@plt>
mov    %rax,-0x130(%rbp)
cmpq   $0x0,-0x130(%rbp)
jne    11b7 <drawcharseg+0x87>
jmp    117d <drawcharseg+0x4d>
mov    -0x130(%rbp),%rax
mov    -0x128(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,-0x134(%rbp)
mov    -0x134(%rbp),%eax
shl    $0x2,%eax
cltq
mov    -0x120(%rbp,%rax,4),%eax
imul   -0x1c(%rbp),%eax
mov    %eax,-0x138(%rbp)
mov    -0x134(%rbp),%eax
shl    $0x2,%eax
add    $0x1,%eax
cltq
mov    -0x120(%rbp,%rax,4),%eax
imul   -0x1c(%rbp),%eax
mov    %eax,-0x140(%rbp)
mov    -0x134(%rbp),%eax
shl    $0x2,%eax
add    $0x2,%eax
cltq
mov    -0x120(%rbp,%rax,4),%eax
imul   -0x1c(%rbp),%eax
mov    %eax,-0x13c(%rbp)
mov    -0x134(%rbp),%eax
shl    $0x2,%eax
add    $0x3,%eax
cltq
mov    -0x120(%rbp,%rax,4),%eax
imul   -0x1c(%rbp),%eax
mov    %eax,-0x144(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0xc(%rbp),%esi
add    -0x138(%rbp),%esi
mov    -0x10(%rbp),%edx
add    -0x140(%rbp),%edx
mov    -0xc(%rbp),%ecx
add    -0x13c(%rbp),%ecx
mov    -0x10(%rbp),%r8d
add    -0x144(%rbp),%r8d
mov    -0x20(%rbp),%r9d
mov    0x10(%rbp),%r10d
mov    0x18(%rbp),%eax
mov    %r10d,(%rsp)
mov    %eax,0x8(%rsp)
call   1050 <drawline@plt>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    117d <drawcharseg+0x4d>
add    $0x160,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<drawcharseg>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %r9d,0xc(%rsp)
mov    %edx,0x8(%rsp)
mov    %rdi,0x10(%rsp)
mov    (%rcx),%r14b
test   %r14b,%r14b
je     120f <drawcharseg+0xef>
mov    %r8d,%ebp
mov    %rcx,%rbx
mov    %esi,%r12d
lea    0xfa8(%rip),%r15
lea    0xea1(%rip),%r13
jmp    1179 <drawcharseg+0x59>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
test   %r14b,%r14b
je     120f <drawcharseg+0xef>
movsbl %r14b,%esi
mov    %r15,%rdi
call   1030 <strchr@plt>
test   %rax,%rax
je     1170 <drawcharseg+0x50>
sub    %r15d,%eax
lea    0x0(,%rax,4),%ecx
movslq %ecx,%rcx
mov    0x0(%r13,%rcx,4),%esi
imul   %ebp,%esi
lea    0x1(,%rax,4),%ecx
movslq %ecx,%rcx
mov    0x0(%r13,%rcx,4),%edx
imul   %ebp,%edx
lea    0x2(,%rax,4),%ecx
movslq %ecx,%rcx
mov    0x0(%r13,%rcx,4),%ecx
imul   %ebp,%ecx
lea    0x3(,%rax,4),%eax
cltq
mov    0x0(%r13,%rax,4),%r8d
imul   %ebp,%r8d
add    %r12d,%esi
mov    0x8(%rsp),%eax
add    %eax,%edx
add    %r12d,%ecx
add    %eax,%r8d
mov    0x10(%rsp),%rdi
mov    0xc(%rsp),%r9d
mov    0x58(%rsp),%eax
push   %rax
mov    0x58(%rsp),%eax
push   %rax
call   1040 <drawline@plt>
add    $0x10,%rsp
movzbl 0x1(%rbx),%r14d
add    $0x1,%rbx
jmp    1170 <drawcharseg+0x50>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.raster = type { i32 }
@__const.drawcharseg.segments = [64 x i32] [i32 0, i32 4, i32 0, i32 2, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 2, i32 0, i32 2, i32 0, i32 2, i32 2, i32 2, i32 2, i32 2, i32 4, i32 2, i32 4, i32 1, i32 4, i32 1, i32 4, i32 0, i32 4, i32 0, i32 4, i32 1, i32 2, i32 0, i32 2, i32 1, i32 2, i32 0, i32 0, i32 1, i32 2, i32 1, i32 0, i32 1, i32 2, i32 2, i32 0, i32 1, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 4, i32 1, i32 2, i32 1, i32 4, i32 1, i32 2]
@.str = [17 x i8] c"0123456789abcdef\00"
define void @drawcharseg(%struct.raster* %0, i32 %1, i32 %2, i8* %3, i32 %4, i32 %5, i32 %6, i32 %7) {
%9 = alloca %struct.raster*
%10 = alloca i32
%11 = alloca i32
%12 = alloca i8*
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca [64 x i32]
%18 = alloca i8*
%19 = alloca i8*
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
store %struct.raster* %0, %struct.raster** %9
store i32 %1, i32* %10
store i32 %2, i32* %11
store i8* %3, i8** %12
store i32 %4, i32* %13
store i32 %5, i32* %14
store i32 %6, i32* %15
store i32 %7, i32* %16
%25 = bitcast [64 x i32]* %17 to i8*
store i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0), i8** %18
br label %26
26: ; preds = %38, %37, %8
%27 = load i8*, i8** %12
%28 = load i8, i8* %27
%29 = icmp ne i8 %28, 0
br i1 %29, label %30, label %95
30: ; preds = %26
%31 = load i8*, i8** %18
%32 = load i8*, i8** %12
%33 = load i8, i8* %32
%34 = call i8* @strchr(i8* %31, i8 signext %33)
store i8* %34, i8** %19
%35 = load i8*, i8** %19
%36 = icmp ne i8* %35, null
br i1 %36, label %38, label %37
37: ; preds = %30
br label %26
38: ; preds = %30
%39 = load i8*, i8** %19
%40 = load i8*, i8** %18
%41 = ptrtoint i8* %39 to i64
%42 = ptrtoint i8* %40 to i64
%43 = sub i64 %41, %42
%44 = trunc i64 %43 to i32
store i32 %44, i32* %20
%45 = load i32, i32* %20
%46 = mul nsw i32 %45, 4
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds [64 x i32], [64 x i32]* %17, i64 0, i64 %47
%49 = load i32, i32* %48
%50 = load i32, i32* %13
%51 = mul nsw i32 %49, %50
store i32 %51, i32* %21
%52 = load i32, i32* %20
%53 = mul nsw i32 %52, 4
%54 = add nsw i32 %53, 1
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds [64 x i32], [64 x i32]* %17, i64 0, i64 %55
%57 = load i32, i32* %56
%58 = load i32, i32* %13
%59 = mul nsw i32 %57, %58
store i32 %59, i32* %23
%60 = load i32, i32* %20
%61 = mul nsw i32 %60, 4
%62 = add nsw i32 %61, 2
%63 = sext i32 %62 to i64
%64 = getelementptr inbounds [64 x i32], [64 x i32]* %17, i64 0, i64 %63
%65 = load i32, i32* %64
%66 = load i32, i32* %13
%67 = mul nsw i32 %65, %66
store i32 %67, i32* %22
%68 = load i32, i32* %20
%69 = mul nsw i32 %68, 4
%70 = add nsw i32 %69, 3
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds [64 x i32], [64 x i32]* %17, i64 0, i64 %71
%73 = load i32, i32* %72
%74 = load i32, i32* %13
%75 = mul nsw i32 %73, %74
store i32 %75, i32* %24
%76 = load %struct.raster*, %struct.raster** %9
%77 = load i32, i32* %10
%78 = load i32, i32* %21
%79 = add nsw i32 %77, %78
%80 = load i32, i32* %11
%81 = load i32, i32* %23
%82 = add nsw i32 %80, %81
%83 = load i32, i32* %10
%84 = load i32, i32* %22
%85 = add nsw i32 %83, %84
%86 = load i32, i32* %11
%87 = load i32, i32* %24
%88 = add nsw i32 %86, %87
%89 = load i32, i32* %14
%90 = load i32, i32* %15
%91 = load i32, i32* %16
%92 = call i32 @drawline(%struct.raster* %76, i32 %79, i32 %82, i32 %85, i32 %88, i32 %89, i32 %90, i32 %91)
%93 = load i8*, i8** %12
%94 = getelementptr inbounds i8, i8* %93, i32 1
store i8* %94, i8** %12
br label %26
95: ; preds = %26
ret void
}

LLVM IR (-O2):
%struct.raster = type { i32 }
@__const.drawcharseg.segments = [64 x i32] [i32 0, i32 4, i32 0, i32 2, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 2, i32 0, i32 2, i32 0, i32 2, i32 2, i32 2, i32 2, i32 2, i32 4, i32 2, i32 4, i32 1, i32 4, i32 1, i32 4, i32 0, i32 4, i32 0, i32 4, i32 1, i32 2, i32 0, i32 2, i32 1, i32 2, i32 0, i32 0, i32 1, i32 2, i32 1, i32 0, i32 1, i32 2, i32 2, i32 0, i32 1, i32 2, i32 2, i32 2, i32 1, i32 2, i32 2, i32 4, i32 1, i32 2, i32 1, i32 4, i32 1, i32 2]
@.str = [17 x i8] c"0123456789abcdef\00"
define void @drawcharseg(%struct.raster* %0, i32 %1, i32 %2, i8* nocapture %3, i32 %4, i32 %5, i32 %6, i32 %7) {
%9 = load i8, i8* %3
%10 = icmp eq i8 %9, 0
br i1 %10, label %51, label %11
11: ; preds = %8, %47
%12 = phi i8 [ %48, %47 ], [ %9, %8 ]
%13 = phi i8* [ %49, %47 ], [ %3, %8 ]
%14 = tail call i8* @strchr(i8* dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0), i8 signext %12)
%15 = icmp eq i8* %14, null
br i1 %15, label %47, label %16
16: ; preds = %11
%17 = ptrtoint i8* %14 to i64
%18 = trunc i64 %17 to i32
%19 = sub i32 %18, ptrtoint ([17 x i8]* @.str to i32)
%20 = shl nsw i32 %19, 2
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds [64 x i32], [64 x i32]* @__const.drawcharseg.segments, i64 0, i64 %21
%23 = load i32, i32* %22
%24 = mul nsw i32 %23, %4
%25 = or i32 %20, 1
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds [64 x i32], [64 x i32]* @__const.drawcharseg.segments, i64 0, i64 %26
%28 = load i32, i32* %27
%29 = mul nsw i32 %28, %4
%30 = or i32 %20, 2
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds [64 x i32], [64 x i32]* @__const.drawcharseg.segments, i64 0, i64 %31
%33 = load i32, i32* %32
%34 = mul nsw i32 %33, %4
%35 = or i32 %20, 3
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds [64 x i32], [64 x i32]* @__const.drawcharseg.segments, i64 0, i64 %36
%38 = load i32, i32* %37
%39 = mul nsw i32 %38, %4
%40 = add nsw i32 %24, %1
%41 = add nsw i32 %29, %2
%42 = add nsw i32 %34, %1
%43 = add nsw i32 %39, %2
%44 = tail call i32 @drawline(%struct.raster* %0, i32 %40, i32 %41, i32 %42, i32 %43, i32 %5, i32 %6, i32 %7)
%45 = getelementptr inbounds i8, i8* %13, i64 1
%46 = load i8, i8* %45
br label %47
47: ; preds = %11, %16
%48 = phi i8 [ %46, %16 ], [ %12, %11 ]
%49 = phi i8* [ %45, %16 ], [ %13, %11 ]
%50 = icmp eq i8 %48, 0
br i1 %50, label %51, label %11
51: ; preds = %47, %8
ret void
}