#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 */

/* Variables and functions */
int /*<<< orphan*/ out_printc(char);
int /*<<< orphan*/ out_prints(char *);
void out_printn(unsigned long number, int base) {
  char *str;
  int i = 0;
  if (number == 0) {
    str[i] = '0';
    i++;
    str[i] = '\0';
    out_prints(str);
    return;
  } else {
    if (base == 10) {
      int i, rem, len = 0, n = number;
      while (n != 0) {
        len++;
        n /= 10;
      }
      for (i = 0; i < len; i++) {
        rem = number % 10;
        number = number / 10;
        str[len - (i + 1)] = rem + '0';
      }
      str[len] = '\0';
      out_prints(str);
    } else if (base == 16) {
      unsigned long dec_num = number, quot;
      int i = 1, j, temp;
      char hex_num[100];
      quot = dec_num;
      while (quot != 0) {
        temp = quot % 16;
        if (temp < 10)
          temp = temp + 48;
        else
          temp = temp + 55;
        hex_num[i++] = temp;
        quot = quot / 16;
      }
      out_prints("0x");
      for (j = i - 1; j > 0; j--)
        out_printc(hex_num[j]);
    } else if (base == 8) {
      int rem, i = 1, octal = 0;
      while (number != 0) {
        rem = number % 8;
        number /= 8;
        octal += rem * i;
        i *= 10;
      }
      out_printn(octal, 10);
    } else if (base == 2) {
      int c, d, count = 0;
      for (c = 31; c >= 0; c--) {
        d = number >> c;
        if (d & 1)
          *(str + count) = 1 + '0';
        else
          *(str + count) = 0 + '0';
        count++;
      }
      *(str + count) = '\0';
      out_prints(str);
    }
  }
}


x86 assembly (clang, -O0):
<out_printn>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpq   $0x0,-0x8(%rbp)
jne    1183 <out_printn+0x53>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movb   $0x30,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x18(%rbp),%rdi
call   1050 <out_prints@plt>
jmp    1449 <out_printn+0x319>
cmpl   $0xa,-0xc(%rbp)
jne    123e <out_printn+0x10e>
movl   $0x0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
je     11c1 <out_printn+0x91>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %eax,-0x2c(%rbp)
jmp    119b <out_printn+0x6b>
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x28(%rbp),%eax
jge    1224 <out_printn+0xf4>
mov    -0x8(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
mov    %edx,%eax
mov    %eax,-0x24(%rbp)
mov    -0x8(%rbp),%rax
mov    $0xa,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,-0x8(%rbp)
mov    -0x24(%rbp),%eax
add    $0x30,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    -0x20(%rbp),%esi
add    $0x1,%esi
sub    %esi,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    11c8 <out_printn+0x98>
mov    -0x18(%rbp),%rax
movslq -0x28(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x18(%rbp),%rdi
call   1050 <out_prints@plt>
jmp    1444 <out_printn+0x314>
cmpl   $0x10,-0xc(%rbp)
jne    1303 <out_printn+0x1d3>
mov    -0x8(%rbp),%rax
mov    %rax,-0x38(%rbp)
movl   $0x1,-0x44(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
je     12c0 <out_printn+0x190>
mov    -0x40(%rbp),%rax
and    $0xf,%rax
mov    %eax,-0x4c(%rbp)
cmpl   $0xa,-0x4c(%rbp)
jge    128d <out_printn+0x15d>
mov    -0x4c(%rbp),%eax
add    $0x30,%eax
mov    %eax,-0x4c(%rbp)
jmp    1296 <out_printn+0x166>
mov    -0x4c(%rbp),%eax
add    $0x37,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
mov    %al,%cl
mov    -0x44(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x44(%rbp)
cltq
mov    %cl,-0xb0(%rbp,%rax,1)
mov    -0x40(%rbp),%rax
shr    $0x4,%rax
mov    %rax,-0x40(%rbp)
jmp    125f <out_printn+0x12f>
lea    0xd39(%rip),%rdi
call   1050 <out_prints@plt>
mov    -0x44(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x48(%rbp)
cmpl   $0x0,-0x48(%rbp)
jle    12fe <out_printn+0x1ce>
movslq -0x48(%rbp),%rax
movsbl -0xb0(%rbp,%rax,1),%edi
ff
call   1040 <out_printc@plt>
mov    -0x48(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x48(%rbp)
jmp    12d5 <out_printn+0x1a5>
jmp    143f <out_printn+0x30f>
cmpl   $0x8,-0xc(%rbp)
jne    1387 <out_printn+0x257>
movl   $0x1,-0xb8(%rbp)
movl   $0x0,-0xbc(%rbp)
cmpq   $0x0,-0x8(%rbp)
je     1371 <out_printn+0x241>
mov    -0x8(%rbp),%rax
and    $0x7,%rax
mov    %eax,-0xb4(%rbp)
mov    -0x8(%rbp),%rax
shr    $0x3,%rax
mov    %rax,-0x8(%rbp)
mov    -0xb4(%rbp),%eax
imul   -0xb8(%rbp),%eax
add    -0xbc(%rbp),%eax
mov    %eax,-0xbc(%rbp)
imul   $0xa,-0xb8(%rbp),%eax
mov    %eax,-0xb8(%rbp)
jmp    1321 <out_printn+0x1f1>
movslq -0xbc(%rbp),%rdi
mov    $0xa,%esi
call   1030 <out_printn@plt>
jmp    143a <out_printn+0x30a>
cmpl   $0x2,-0xc(%rbp)
jne    1435 <out_printn+0x305>
movl   $0x0,-0xc8(%rbp)
movl   $0x1f,-0xc0(%rbp)
cmpl   $0x0,-0xc0(%rbp)
jl     141d <out_printn+0x2ed>
mov    -0x8(%rbp),%rax
mov    -0xc0(%rbp),%ecx
shr    %cl,%rax
mov    %eax,-0xc4(%rbp)
mov    -0xc4(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     13eb <out_printn+0x2bb>
mov    -0x18(%rbp),%rax
movslq -0xc8(%rbp),%rcx
movb   $0x31,(%rax,%rcx,1)
jmp    13fa <out_printn+0x2ca>
mov    -0x18(%rbp),%rax
movslq -0xc8(%rbp),%rcx
movb   $0x30,(%rax,%rcx,1)
mov    -0xc8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc8(%rbp)
mov    -0xc0(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc0(%rbp)
jmp    13a5 <out_printn+0x275>
mov    -0x18(%rbp),%rax
movslq -0xc8(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x18(%rbp),%rdi
call   1050 <out_prints@plt>
jmp    143a <out_printn+0x30a>
jmp    143f <out_printn+0x30f>
jmp    1444 <out_printn+0x314>
jmp    1449 <out_printn+0x319>
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<out_printn>:
cmp    $0x10,%esi
je     1136 <out_printn+0x16>
cmp    $0x8,%esi
jne    11b9 <out_printn+0x99>
xchg   %ax,%ax
shr    $0x3,%rdi
jmp    1130 <out_printn+0x10>
push   %rbx
sub    $0x70,%rsp
mov    $0x1,%ebx
mov    %rdi,%rax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %edi,%ecx
and    $0xf,%ecx
lea    0x37(%rcx),%edx
lea    0x30(%rcx),%esi
cmp    $0xa,%ecx
movzbl %sil,%ecx
movzbl %dl,%edx
cmovb  %ecx,%edx
mov    %dl,(%rsp,%rbx,1)
add    $0x1,%rbx
shr    $0x4,%rax
cmp    $0xf,%rdi
mov    %rax,%rdi
ja     1150 <out_printn+0x30>
lea    0xe7d(%rip),%rdi
call   1040 <out_prints@plt>
cmp    $0x2,%ebx
jl     11b4 <out_printn+0x94>
add    $0x1,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movsbl -0x2(%rsp,%rbx,1),%edi
call   1030 <out_printc@plt>
add    $0xffffffffffffffff,%rbx
cmp    $0x2,%rbx
ja     11a0 <out_printn+0x80>
add    $0x70,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [3 x i8] c"0x\00"
define void @out_printn(i64 %0, i32 %1) {
%3 = alloca i64
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i64
%12 = alloca i64
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca [100 x i8]
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
store i64 %0, i64* %3
store i32 %1, i32* %4
store i32 0, i32* %6
%23 = load i64, i64* %3
%24 = icmp eq i64 %23, 0
br i1 %24, label %25, label %38
25: ; preds = %2
%26 = load i8*, i8** %5
%27 = load i32, i32* %6
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds i8, i8* %26, i64 %28
store i8 48, i8* %29
%30 = load i32, i32* %6
%31 = add nsw i32 %30, 1
store i32 %31, i32* %6
%32 = load i8*, i8** %5
%33 = load i32, i32* %6
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds i8, i8* %32, i64 %34
store i8 0, i8* %35
%36 = load i8*, i8** %5
%37 = call i32 @out_prints(i8* %36)
br label %196
38: ; preds = %2
%39 = load i32, i32* %4
%40 = icmp eq i32 %39, 10
br i1 %40, label %41, label %83
41: ; preds = %38
store i32 0, i32* %9
%42 = load i64, i64* %3
%43 = trunc i64 %42 to i32
store i32 %43, i32* %10
br label %44
44: ; preds = %47, %41
%45 = load i32, i32* %10
%46 = icmp ne i32 %45, 0
br i1 %46, label %47, label %52
47: ; preds = %44
%48 = load i32, i32* %9
%49 = add nsw i32 %48, 1
store i32 %49, i32* %9
%50 = load i32, i32* %10
%51 = sdiv i32 %50, 10
store i32 %51, i32* %10
br label %44
52: ; preds = %44
store i32 0, i32* %7
br label %53
53: ; preds = %73, %52
%54 = load i32, i32* %7
%55 = load i32, i32* %9
%56 = icmp slt i32 %54, %55
br i1 %56, label %57, label %76
57: ; preds = %53
%58 = load i64, i64* %3
%59 = urem i64 %58, 10
%60 = trunc i64 %59 to i32
store i32 %60, i32* %8
%61 = load i64, i64* %3
%62 = udiv i64 %61, 10
store i64 %62, i64* %3
%63 = load i32, i32* %8
%64 = add nsw i32 %63, 48
%65 = trunc i32 %64 to i8
%66 = load i8*, i8** %5
%67 = load i32, i32* %9
%68 = load i32, i32* %7
%69 = add nsw i32 %68, 1
%70 = sub nsw i32 %67, %69
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds i8, i8* %66, i64 %71
store i8 %65, i8* %72
br label %73
73: ; preds = %57
%74 = load i32, i32* %7
%75 = add nsw i32 %74, 1
store i32 %75, i32* %7
br label %53
76: ; preds = %53
%77 = load i8*, i8** %5
%78 = load i32, i32* %9
%79 = sext i32 %78 to i64
%80 = getelementptr inbounds i8, i8* %77, i64 %79
store i8 0, i8* %80
%81 = load i8*, i8** %5
%82 = call i32 @out_prints(i8* %81)
br label %195
83: ; preds = %38
%84 = load i32, i32* %4
%85 = icmp eq i32 %84, 16
br i1 %85, label %86, label %130
86: ; preds = %83
%87 = load i64, i64* %3
store i64 %87, i64* %11
store i32 1, i32* %13
%88 = load i64, i64* %11
store i64 %88, i64* %12
br label %89
89: ; preds = %104, %86
%90 = load i64, i64* %12
%91 = icmp ne i64 %90, 0
br i1 %91, label %92, label %113
92: ; preds = %89
%93 = load i64, i64* %12
%94 = urem i64 %93, 16
%95 = trunc i64 %94 to i32
store i32 %95, i32* %15
%96 = load i32, i32* %15
%97 = icmp slt i32 %96, 10
br i1 %97, label %98, label %101
98: ; preds = %92
%99 = load i32, i32* %15
%100 = add nsw i32 %99, 48
store i32 %100, i32* %15
br label %104
101: ; preds = %92
%102 = load i32, i32* %15
%103 = add nsw i32 %102, 55
store i32 %103, i32* %15
br label %104
104: ; preds = %101, %98
%105 = load i32, i32* %15
%106 = trunc i32 %105 to i8
%107 = load i32, i32* %13
%108 = add nsw i32 %107, 1
store i32 %108, i32* %13
%109 = sext i32 %107 to i64
%110 = getelementptr inbounds [100 x i8], [100 x i8]* %16, i64 0, i64 %109
store i8 %106, i8* %110
%111 = load i64, i64* %12
%112 = udiv i64 %111, 16
store i64 %112, i64* %12
br label %89
113: ; preds = %89
%114 = call i32 @out_prints(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
%115 = load i32, i32* %13
%116 = sub nsw i32 %115, 1
store i32 %116, i32* %14
br label %117
117: ; preds = %126, %113
%118 = load i32, i32* %14
%119 = icmp sgt i32 %118, 0
br i1 %119, label %120, label %129
120: ; preds = %117
%121 = load i32, i32* %14
%122 = sext i32 %121 to i64
%123 = getelementptr inbounds [100 x i8], [100 x i8]* %16, i64 0, i64 %122
%124 = load i8, i8* %123
%125 = call i32 @out_printc(i8 signext %124)
br label %126
126: ; preds = %120
%127 = load i32, i32* %14
%128 = add nsw i32 %127, -1
store i32 %128, i32* %14
br label %117
129: ; preds = %117
br label %194
130: ; preds = %83
%131 = load i32, i32* %4
%132 = icmp eq i32 %131, 8
br i1 %132, label %133, label %153
133: ; preds = %130
store i32 1, i32* %18
store i32 0, i32* %19
br label %134
134: ; preds = %137, %133
%135 = load i64, i64* %3
%136 = icmp ne i64 %135, 0
br i1 %136, label %137, label %150
137: ; preds = %134
%138 = load i64, i64* %3
%139 = urem i64 %138, 8
%140 = trunc i64 %139 to i32
store i32 %140, i32* %17
%141 = load i64, i64* %3
%142 = udiv i64 %141, 8
store i64 %142, i64* %3
%143 = load i32, i32* %17
%144 = load i32, i32* %18
%145 = mul nsw i32 %143, %144
%146 = load i32, i32* %19
%147 = add nsw i32 %146, %145
store i32 %147, i32* %19
%148 = load i32, i32* %18
%149 = mul nsw i32 %148, 10
store i32 %149, i32* %18
br label %134
150: ; preds = %134
%151 = load i32, i32* %19
%152 = sext i32 %151 to i64
br label %193
153: ; preds = %130
%154 = load i32, i32* %4
%155 = icmp eq i32 %154, 2
br i1 %155, label %156, label %192
156: ; preds = %153
store i32 0, i32* %22
store i32 31, i32* %20
br label %157
157: ; preds = %182, %156
%158 = load i32, i32* %20
%159 = icmp sge i32 %158, 0
br i1 %159, label %160, label %185
160: ; preds = %157
%161 = load i64, i64* %3
%162 = load i32, i32* %20
%163 = zext i32 %162 to i64
%164 = lshr i64 %161, %163
%165 = trunc i64 %164 to i32
store i32 %165, i32* %21
%166 = load i32, i32* %21
%167 = and i32 %166, 1
%168 = icmp ne i32 %167, 0
br i1 %168, label %169, label %174
169: ; preds = %160
%170 = load i8*, i8** %5
%171 = load i32, i32* %22
%172 = sext i32 %171 to i64
%173 = getelementptr inbounds i8, i8* %170, i64 %172
store i8 49, i8* %173
br label %179
174: ; preds = %160
%175 = load i8*, i8** %5
%176 = load i32, i32* %22
%177 = sext i32 %176 to i64
%178 = getelementptr inbounds i8, i8* %175, i64 %177
store i8 48, i8* %178
br label %179
179: ; preds = %174, %169
%180 = load i32, i32* %22
%181 = add nsw i32 %180, 1
store i32 %181, i32* %22
br label %182
182: ; preds = %179
%183 = load i32, i32* %20
%184 = add nsw i32 %183, -1
store i32 %184, i32* %20
br label %157
185: ; preds = %157
%186 = load i8*, i8** %5
%187 = load i32, i32* %22
%188 = sext i32 %187 to i64
%189 = getelementptr inbounds i8, i8* %186, i64 %188
store i8 0, i8* %189
%190 = load i8*, i8** %5
%191 = call i32 @out_prints(i8* %190)
br label %192
192: ; preds = %185, %153
br label %193
193: ; preds = %192, %150
br label %194
194: ; preds = %193, %129
br label %195
195: ; preds = %194, %76
br label %196
196: ; preds = %25, %195
ret void
}

LLVM IR (-O2):
@.str = [3 x i8] c"0x\00"
define void @out_printn(i64 %0, i32 %1) {
%3 = alloca [100 x i8]
%4 = icmp ne i64 %0, 0
tail call void @llvm.assume(i1 %4)
switch i32 %1, label %39 [
i32 8, label %35
i32 16, label %5
]
5: ; preds = %2
%6 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 0
br label %7
7: ; preds = %5, %7
%8 = phi i64 [ 1, %5 ], [ %17, %7 ]
%9 = phi i64 [ %0, %5 ], [ %19, %7 ]
%10 = trunc i64 %9 to i32
%11 = and i32 %10, 15
%12 = icmp ult i32 %11, 10
%13 = or i32 %11, 48
%14 = add nuw nsw i32 %11, 55
%15 = select i1 %12, i32 %13, i32 %14
%16 = trunc i32 %15 to i8
%17 = add nuw nsw i64 %8, 1
%18 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 %8
store i8 %16, i8* %18
%19 = lshr i64 %9, 4
%20 = icmp ult i64 %9, 16
br i1 %20, label %21, label %7
21: ; preds = %7
%22 = trunc i64 %17 to i32
%23 = tail call i32 @out_prints(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
%24 = icmp sgt i32 %22, 1
br i1 %24, label %25, label %34
25: ; preds = %21
%26 = and i64 %17, 4294967295
br label %27
27: ; preds = %25, %27
%28 = phi i64 [ %26, %25 ], [ %29, %27 ]
%29 = add nsw i64 %28, -1
%30 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 %29
%31 = load i8, i8* %30
%32 = tail call i32 @out_printc(i8 signext %31)
%33 = icmp ugt i64 %28, 2
br i1 %33, label %27, label %34
34: ; preds = %27, %21
br label %39
35: ; preds = %2, %35
%36 = phi i64 [ %37, %35 ], [ %0, %2 ]
%37 = lshr i64 %36, 3
%38 = icmp ugt i64 %36, 7
br label %35
39: ; preds = %34, %2
ret void
}