#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 riku_devfs_node {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ strlen(char *);
int /*<<< orphan*/ x86vga_putch(struct riku_devfs_node *, int /*<<< orphan*/);
int /*<<< orphan*/ x86vga_puts(struct riku_devfs_node *, char *,
                               int /*<<< orphan*/);
void x86vga_putdec(struct riku_devfs_node *self, uintptr_t n) {
  if (n == 0) {
    x86vga_putch(self, '0');
    return;
  }
  int acc = n;
  char c[64];
  int i = 0;
  while (acc > 0) {
    c[i] = '0' + acc % 10;
    acc /= 10;
    i++;
  }
  c[i] = 0;
  char c2[64];
  c2[i--] = 0;
  int j = 0;
  while (i >= 0) {
    c2[i--] = c[j++];
  }
  x86vga_puts(self, c2, strlen(c2));
}


x86 assembly (clang, -O0):
<x86vga_putdec>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1161 <x86vga_putdec+0x31>
mov    -0x8(%rbp),%rdi
mov    $0x30,%esi
call   1040 <x86vga_putch@plt>
jmp    1249 <x86vga_putdec+0x119>
mov    -0x10(%rbp),%rax
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x64(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    11ad <x86vga_putdec+0x7d>
mov    -0x14(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
add    $0x30,%edx
mov    %dl,%cl
movslq -0x64(%rbp),%rax
mov    %cl,-0x60(%rbp,%rax,1)
mov    -0x14(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %eax,-0x14(%rbp)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    116f <x86vga_putdec+0x3f>
movslq -0x64(%rbp),%rax
movb   $0x0,-0x60(%rbp,%rax,1)
mov    -0x64(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x64(%rbp)
cltq
movb   $0x0,-0xb0(%rbp,%rax,1)
movl   $0x0,-0xb4(%rbp)
cmpl   $0x0,-0x64(%rbp)
jl     120f <x86vga_putdec+0xdf>
mov    -0xb4(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0xb4(%rbp)
cltq
mov    -0x60(%rbp,%rax,1),%cl
mov    -0x64(%rbp),%eax
mov    %eax,%edx
add    $0xffffffff,%edx
mov    %edx,-0x64(%rbp)
cltq
mov    %cl,-0xb0(%rbp,%rax,1)
jmp    11d5 <x86vga_putdec+0xa5>
mov    -0x8(%rbp),%rax
mov    %rax,-0xc8(%rbp)
lea    -0xb0(%rbp),%rax
mov    %rax,-0xc0(%rbp)
lea    -0xb0(%rbp),%rdi
call   1030 <strlen@plt>
mov    -0xc8(%rbp),%rdi
mov    -0xc0(%rbp),%rsi
mov    %eax,%edx
call   1050 <x86vga_puts@plt>
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<x86vga_putdec>:
push   %r14
push   %rbx
sub    $0x88,%rsp
mov    %rdi,%r14
test   %rsi,%rsi
je     123d <x86vga_putdec+0x10d>
test   %esi,%esi
jle    1254 <x86vga_putdec+0x124>
xor    %eax,%eax
mov    $0xcccccccd,%ecx
cs nopw 0x0(%rax,%rax,1)
nop
mov    %esi,%edx
imul   %rcx,%rdx
shr    $0x23,%rdx
lea    (%rdx,%rdx,1),%edi
lea    (%rdi,%rdi,4),%edi
mov    %esi,%ebx
sub    %edi,%ebx
or     $0x30,%bl
mov    %bl,0x40(%rsp,%rax,1)
add    $0x1,%rax
cmp    $0x9,%esi
mov    %edx,%esi
ja     1160 <x86vga_putdec+0x30>
mov    %eax,%r8d
movb   $0x0,0x40(%rsp,%r8,1)
movb   $0x0,(%rsp,%r8,1)
test   %eax,%eax
jle    1258 <x86vga_putdec+0x128>
cmp    $0x8,%r8d
jae    127b <x86vga_putdec+0x14b>
xor    %ecx,%ecx
mov    %r8,%rsi
mov    %eax,%edx
sub    %ecx,%edx
mov    %rcx,%rdi
not    %rdi
add    %rdi,%r8
test   $0x3,%dl
je     11e8 <x86vga_putdec+0xb8>
mov    %eax,%edx
sub    %cl,%dl
movzbl %dl,%edx
and    $0x3,%edx
nopw   0x0(%rax,%rax,1)
add    $0xffffffffffffffff,%rsi
movzbl 0x40(%rsp,%rcx,1),%ebx
add    $0x1,%rcx
mov    %esi,%edi
mov    %bl,(%rsp,%rdi,1)
add    $0xffffffffffffffff,%rdx
jne    11d0 <x86vga_putdec+0xa0>
cmp    $0x3,%r8
jb     1258 <x86vga_putdec+0x128>
mov    $0xfffffffe,%r8d
mov    %eax,%r9d
nopw   0x0(%rax,%rax,1)
lea    (%rsi,%r8,1),%rdi
lea    0x1(%rdi),%ebx
movzbl 0x40(%rsp,%rcx,1),%edx
movzbl 0x41(%rsp,%rcx,1),%eax
mov    %dl,(%rsp,%rbx,1)
mov    %edi,%edx
mov    %al,(%rsp,%rdx,1)
add    $0xffffffff,%edi
movzbl 0x42(%rsp,%rcx,1),%eax
mov    %al,(%rsp,%rdi,1)
add    $0xfffffffffffffffc,%rsi
movzbl 0x43(%rsp,%rcx,1),%eax
add    $0x4,%rcx
mov    %esi,%edx
mov    %al,(%rsp,%rdx,1)
cmp    %rcx,%r9
jne    1200 <x86vga_putdec+0xd0>
jmp    1258 <x86vga_putdec+0x128>
mov    %r14,%rdi
mov    $0x30,%esi
add    $0x88,%rsp
pop    %rbx
pop    %r14
jmp    1040 <x86vga_putch@plt>
movb   $0x0,(%rsp)
mov    %rsp,%rbx
mov    %rbx,%rdi
call   1030 <strlen@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    %eax,%edx
call   1050 <x86vga_puts@plt>
add    $0x88,%rsp
pop    %rbx
pop    %r14
ret
lea    -0x1(%r8),%rdx
lea    -0x1(%rax),%esi
xor    %ecx,%ecx
cmp    %edx,%esi
jb     11a8 <x86vga_putdec+0x78>
shr    $0x20,%rdx
mov    %r8,%rsi
jne    11ab <x86vga_putdec+0x7b>
cmp    $0x20,%r8d
jae    12a6 <x86vga_putdec+0x176>
xor    %ecx,%ecx
jmp    1369 <x86vga_putdec+0x239>
lea    -0x1(%rax),%rdi
mov    %eax,%r9d
mov    %eax,%esi
and    $0x1f,%esi
mov    %r8,%rcx
sub    %rsi,%rcx
sub    %rsi,%r9
xor    %edx,%edx
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movdqa 0x40(%rsp,%rdx,1),%xmm1
movdqa 0x50(%rsp,%rdx,1),%xmm2
mov    %edi,%ebx
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm1,-0xf(%rsp,%rbx,1)
movdqa %xmm2,%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm1,%xmm2
movdqu %xmm2,-0x1f(%rsp,%rbx,1)
add    $0x20,%rdx
add    $0xffffffffffffffe0,%rdi
cmp    %rdx,%r9
jne    12d0 <x86vga_putdec+0x1a0>
test   %rsi,%rsi
je     1258 <x86vga_putdec+0x128>
cmp    $0x8,%esi
jb     11ab <x86vga_putdec+0x7b>
mov    %rcx,%rbx
mov    %eax,%r9d
mov    %eax,%esi
and    $0x7,%esi
mov    %r8,%rcx
sub    %rsi,%rcx
mov    %rbx,%rdx
not    %rdx
add    %rax,%rdx
sub    %rsi,%r9
pxor   %xmm0,%xmm0
nopw   0x0(%rax,%rax,1)
movq   0x40(%rsp,%rbx,1),%xmm1
punpcklbw %xmm0,%xmm1
mov    %edx,%edi
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,-0x7(%rsp,%rdi,1)
add    $0x8,%rbx
add    $0xfffffffffffffff8,%rdx
cmp    %rbx,%r9
jne    1390 <x86vga_putdec+0x260>
test   %rsi,%rsi
jne    11ab <x86vga_putdec+0x7b>
jmp    1258 <x86vga_putdec+0x128>

LLVM IR (-O0):
%struct.riku_devfs_node = type { i32 }
define void @x86vga_putdec(%struct.riku_devfs_node* %0, i64 %1) {
%3 = alloca %struct.riku_devfs_node*
%4 = alloca i64
%5 = alloca i32
%6 = alloca [64 x i8]
%7 = alloca i32
%8 = alloca [64 x i8]
%9 = alloca i32
store %struct.riku_devfs_node* %0, %struct.riku_devfs_node** %3
store i64 %1, i64* %4
%10 = load i64, i64* %4
%11 = icmp eq i64 %10, 0
br i1 %11, label %12, label %15
12: ; preds = %2
%13 = load %struct.riku_devfs_node*, %struct.riku_devfs_node** %3
%14 = call i32 @x86vga_putch(%struct.riku_devfs_node* %13, i32 48)
br label %60
15: ; preds = %2
%16 = load i64, i64* %4
%17 = trunc i64 %16 to i32
store i32 %17, i32* %5
store i32 0, i32* %7
br label %18
18: ; preds = %21, %15
%19 = load i32, i32* %5
%20 = icmp sgt i32 %19, 0
br i1 %20, label %21, label %33
21: ; preds = %18
%22 = load i32, i32* %5
%23 = srem i32 %22, 10
%24 = add nsw i32 48, %23
%25 = trunc i32 %24 to i8
%26 = load i32, i32* %7
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 %27
store i8 %25, i8* %28
%29 = load i32, i32* %5
%30 = sdiv i32 %29, 10
store i32 %30, i32* %5
%31 = load i32, i32* %7
%32 = add nsw i32 %31, 1
store i32 %32, i32* %7
br label %18
33: ; preds = %18
%34 = load i32, i32* %7
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 %35
store i8 0, i8* %36
%37 = load i32, i32* %7
%38 = add nsw i32 %37, -1
store i32 %38, i32* %7
%39 = sext i32 %37 to i64
%40 = getelementptr inbounds [64 x i8], [64 x i8]* %8, i64 0, i64 %39
store i8 0, i8* %40
store i32 0, i32* %9
br label %41
41: ; preds = %44, %33
%42 = load i32, i32* %7
%43 = icmp sge i32 %42, 0
br i1 %43, label %44, label %54
44: ; preds = %41
%45 = load i32, i32* %9
%46 = add nsw i32 %45, 1
store i32 %46, i32* %9
%47 = sext i32 %45 to i64
%48 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 %47
%49 = load i8, i8* %48
%50 = load i32, i32* %7
%51 = add nsw i32 %50, -1
store i32 %51, i32* %7
%52 = sext i32 %50 to i64
%53 = getelementptr inbounds [64 x i8], [64 x i8]* %8, i64 0, i64 %52
store i8 %49, i8* %53
br label %41
54: ; preds = %41
%55 = load %struct.riku_devfs_node*, %struct.riku_devfs_node** %3
%56 = getelementptr inbounds [64 x i8], [64 x i8]* %8, i64 0, i64 0
%57 = getelementptr inbounds [64 x i8], [64 x i8]* %8, i64 0, i64 0
%58 = call i32 @strlen(i8* %57)
%59 = call i32 @x86vga_puts(%struct.riku_devfs_node* %55, i8* %56, i32 %58)
br label %60
60: ; preds = %54, %12
ret void
}

LLVM IR (-O2):
%struct.riku_devfs_node = type { i32 }
define void @x86vga_putdec(%struct.riku_devfs_node* %0, i64 %1) {
%3 = alloca [64 x i8]
%4 = alloca [64 x i8]
%5 = icmp eq i64 %1, 0
br i1 %5, label %6, label %8
6: ; preds = %2
%7 = tail call i32 @x86vga_putch(%struct.riku_devfs_node* %0, i32 48)
br label %144
8: ; preds = %2
%9 = trunc i64 %1 to i32
%10 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 0
%11 = icmp sgt i32 %9, 0
br i1 %11, label %15, label %12
12: ; preds = %8
%13 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 0
%14 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 0
store i8 0, i8* %14
br label %140
15: ; preds = %8, %15
%16 = phi i64 [ %23, %15 ], [ 0, %8 ]
%17 = phi i32 [ %22, %15 ], [ %9, %8 ]
%18 = urem i32 %17, 10
%19 = trunc i32 %18 to i8
%20 = or i8 %19, 48
%21 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %16
store i8 %20, i8* %21
%22 = udiv i32 %17, 10
%23 = add nuw i64 %16, 1
%24 = icmp ult i32 %17, 10
br i1 %24, label %25, label %15
25: ; preds = %15
%26 = trunc i64 %23 to i32
%27 = and i64 %23, 4294967295
%28 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %27
store i8 0, i8* %28
%29 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 0
%30 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %27
store i8 0, i8* %30
%31 = icmp sgt i32 %26, 0
br i1 %31, label %32, label %140
32: ; preds = %25
%33 = icmp ult i64 %27, 8
br i1 %33, label %88, label %34
34: ; preds = %32
%35 = add nsw i64 %27, -1
%36 = add i32 %26, -1
%37 = trunc i64 %35 to i32
%38 = icmp ult i32 %36, %37
%39 = icmp ugt i64 %35, 4294967295
%40 = or i1 %38, %39
br i1 %40, label %88, label %41
41: ; preds = %34
%42 = icmp ult i64 %27, 32
br i1 %42, label %69, label %43
43: ; preds = %41
%44 = and i64 %23, 31
%45 = sub nsw i64 %27, %44
br label %46
46: ; preds = %46, %43
%47 = phi i64 [ 0, %43 ], [ %63, %46 ]
%48 = sub i64 %16, %47
%49 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %47
%50 = bitcast i8* %49 to <16 x i8>*
%51 = load <16 x i8>, <16 x i8>* %50
%52 = getelementptr inbounds i8, i8* %49, i64 16
%53 = bitcast i8* %52 to <16 x i8>*
%54 = load <16 x i8>, <16 x i8>* %53
%55 = and i64 %48, 4294967295
%56 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %55
%57 = shufflevector <16 x i8> %51, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%58 = getelementptr inbounds i8, i8* %56, i64 -15
%59 = bitcast i8* %58 to <16 x i8>*
store <16 x i8> %57, <16 x i8>* %59
%60 = shufflevector <16 x i8> %54, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%61 = getelementptr inbounds i8, i8* %56, i64 -31
%62 = bitcast i8* %61 to <16 x i8>*
store <16 x i8> %60, <16 x i8>* %62
%63 = add nuw i64 %47, 32
%64 = icmp eq i64 %63, %45
br i1 %64, label %65, label %46
65: ; preds = %46
%66 = icmp eq i64 %44, 0
br i1 %66, label %140, label %67
67: ; preds = %65
%68 = icmp ult i64 %44, 8
br i1 %68, label %88, label %69
69: ; preds = %41, %67
%70 = phi i64 [ %45, %67 ], [ 0, %41 ]
%71 = and i64 %23, 7
%72 = sub nsw i64 %27, %71
br label %73
73: ; preds = %73, %69
%74 = phi i64 [ %70, %69 ], [ %84, %73 ]
%75 = sub i64 %16, %74
%76 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %74
%77 = bitcast i8* %76 to <8 x i8>*
%78 = load <8 x i8>, <8 x i8>* %77
%79 = and i64 %75, 4294967295
%80 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %79
%81 = shufflevector <8 x i8> %78, <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%82 = getelementptr inbounds i8, i8* %80, i64 -7
%83 = bitcast i8* %82 to <8 x i8>*
store <8 x i8> %81, <8 x i8>* %83
%84 = add nuw i64 %74, 8
%85 = icmp eq i64 %84, %72
br i1 %85, label %86, label %73
86: ; preds = %73
%87 = icmp eq i64 %71, 0
br i1 %87, label %140, label %88
88: ; preds = %34, %32, %67, %86
%89 = phi i64 [ 0, %32 ], [ 0, %34 ], [ %45, %67 ], [ %72, %86 ]
%90 = phi i64 [ %27, %32 ], [ %27, %34 ], [ %44, %67 ], [ %71, %86 ]
%91 = sub i64 %23, %89
%92 = xor i64 %89, -1
%93 = add nsw i64 %27, %92
%94 = and i64 %91, 3
%95 = icmp eq i64 %94, 0
br i1 %95, label %108, label %96
96: ; preds = %88, %96
%97 = phi i64 [ %101, %96 ], [ %89, %88 ]
%98 = phi i64 [ %100, %96 ], [ %90, %88 ]
%99 = phi i64 [ %106, %96 ], [ 0, %88 ]
%100 = add nsw i64 %98, -1
%101 = add nuw nsw i64 %97, 1
%102 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %97
%103 = load i8, i8* %102
%104 = and i64 %100, 4294967295
%105 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %104
store i8 %103, i8* %105
%106 = add i64 %99, 1
%107 = icmp eq i64 %106, %94
br i1 %107, label %108, label %96
108: ; preds = %96, %88
%109 = phi i64 [ %89, %88 ], [ %101, %96 ]
%110 = phi i64 [ %90, %88 ], [ %100, %96 ]
%111 = icmp ult i64 %93, 3
br i1 %111, label %140, label %112
112: ; preds = %108, %112
%113 = phi i64 [ %134, %112 ], [ %109, %108 ]
%114 = phi i64 [ %133, %112 ], [ %110, %108 ]
%115 = add i64 %114, 4294967295
%116 = add nuw nsw i64 %113, 1
%117 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %113
%118 = load i8, i8* %117
%119 = and i64 %115, 4294967295
%120 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %119
store i8 %118, i8* %120
%121 = add i64 %114, 4294967294
%122 = add nuw nsw i64 %113, 2
%123 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %116
%124 = load i8, i8* %123
%125 = and i64 %121, 4294967295
%126 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %125
store i8 %124, i8* %126
%127 = add i64 %114, 4294967293
%128 = add nuw nsw i64 %113, 3
%129 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %122
%130 = load i8, i8* %129
%131 = and i64 %127, 4294967295
%132 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %131
store i8 %130, i8* %132
%133 = add nsw i64 %114, -4
%134 = add nuw nsw i64 %113, 4
%135 = getelementptr inbounds [64 x i8], [64 x i8]* %3, i64 0, i64 %128
%136 = load i8, i8* %135
%137 = and i64 %133, 4294967295
%138 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 %137
store i8 %136, i8* %138
%139 = icmp eq i64 %134, %27
br i1 %139, label %140, label %112
140: ; preds = %108, %112, %65, %86, %12, %25
%141 = getelementptr inbounds [64 x i8], [64 x i8]* %4, i64 0, i64 0
%142 = call i32 @strlen(i8* %141)
%143 = call i32 @x86vga_puts(%struct.riku_devfs_node* %0, i8* %141, i32 %142)
br label %144
144: ; preds = %140, %6
ret void
}