#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 */
typedef int uint8_t;

/* Variables and functions */
char *dump_string(char *outbuf, int outbuf_size, char *inbuf, int inbuf_size) {
  char *outend = &outbuf[outbuf_size - 5], *o = outbuf;
  uint8_t *inend = (void *)&inbuf[inbuf_size], *p = (void *)inbuf;
  while (p < inend && o < outend) {
    uint8_t c = *p++;
    if (c > 31 && c < 127 && c != '\\') {
      *o++ = c;
      continue;
    }
    *o++ = '\\';
    *o++ = 'x';
    *o++ = ((c >> 4) < 10 ? '0' + (c >> 4) : 'a' + (c >> 4) - 10);
    *o++ = ((c & 0x0f) < 10 ? '0' + (c & 0x0f) : 'a' + (c & 0x0f) - 10);
  }
  *o = '\0';
  return outbuf;
}


x86 assembly (clang, -O0):
<dump_string>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
sub    $0x5,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rcx
xor    %eax,%eax
cmp    -0x38(%rbp),%rcx
mov    %al,-0x45(%rbp)
jae    1166 <dump_string+0x66>
mov    -0x30(%rbp),%rax
cmp    -0x28(%rbp),%rax
setb   %al
mov    %al,-0x45(%rbp)
mov    -0x45(%rbp),%al
test   $0x1,%al
jne    1176 <dump_string+0x76>
jmp    1276 <dump_string+0x176>
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x40(%rbp)
mov    (%rax),%eax
mov    %eax,-0x44(%rbp)
cmpl   $0x1f,-0x44(%rbp)
jle    11c3 <dump_string+0xc3>
cmpl   $0x7f,-0x44(%rbp)
jge    11c3 <dump_string+0xc3>
cmpl   $0x5c,-0x44(%rbp)
je     11c3 <dump_string+0xc3>
mov    -0x44(%rbp),%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
jmp    1145 <dump_string+0x45>
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movb   $0x78,(%rax)
mov    -0x44(%rbp),%eax
sar    $0x4,%eax
cmp    $0xa,%eax
jge    1207 <dump_string+0x107>
mov    -0x44(%rbp),%eax
sar    $0x4,%eax
add    $0x30,%eax
mov    %eax,-0x4c(%rbp)
jmp    1216 <dump_string+0x116>
mov    -0x44(%rbp),%eax
sar    $0x4,%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
mov    -0x44(%rbp),%eax
and    $0xf,%eax
cmp    $0xa,%eax
jge    124c <dump_string+0x14c>
mov    -0x44(%rbp),%eax
and    $0xf,%eax
add    $0x30,%eax
mov    %eax,-0x50(%rbp)
jmp    125b <dump_string+0x15b>
mov    -0x44(%rbp),%eax
and    $0xf,%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %eax,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
jmp    1145 <dump_string+0x45>
mov    -0x30(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dump_string>:
mov    %rdi,%rax
test   %ecx,%ecx
jle    119b <dump_string+0x9b>
mov    %rax,%rdi
cmp    $0x6,%esi
jl     119b <dump_string+0x9b>
movslq %esi,%rsi
lea    (%rsi,%rax,1),%r8
add    $0xfffffffffffffffb,%r8
movslq %ecx,%r9
add    %rdx,%r9
add    $0x4,%rdx
mov    %rax,%rdi
nop
mov    -0x4(%rdx),%esi
cmp    $0x5c,%esi
je     1150 <dump_string+0x50>
lea    -0x20(%rsi),%ecx
mov    $0x1,%r11d
cmp    $0x5f,%ecx
jae    1150 <dump_string+0x50>
mov    %rdi,%r10
jmp    1187 <dump_string+0x87>
nopl   0x0(%rax,%rax,1)
movw   $0x785c,(%rdi)
mov    %esi,%ecx
shr    $0x4,%ecx
lea    0x57(%rcx),%r10d
add    $0x30,%ecx
cmp    $0xa0,%esi
cmovge %r10d,%ecx
lea    0x3(%rdi),%r10
mov    %cl,0x2(%rdi)
and    $0xf,%esi
lea    0x30(%rsi),%ecx
cmp    $0xa,%esi
lea    0x57(%rsi),%esi
cmovb  %ecx,%esi
mov    $0x4,%r11d
add    %r11,%rdi
mov    %sil,(%r10)
cmp    %r9,%rdx
jae    119b <dump_string+0x9b>
add    $0x4,%rdx
cmp    %r8,%rdi
jb     1130 <dump_string+0x30>
movb   $0x0,(%rdi)
ret

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

LLVM IR (-O2):
define i8* @dump_string(i8* returned writeonly %0, i32 %1, i8* %2, i32 %3) {
%5 = add nsw i32 %1, -5
%6 = sext i32 %5 to i64
%7 = getelementptr inbounds i8, i8* %0, i64 %6
%8 = sext i32 %3 to i64
%9 = getelementptr inbounds i8, i8* %2, i64 %8
%10 = bitcast i8* %9 to i32*
%11 = icmp sgt i32 %3, 0
%12 = icmp sgt i32 %1, 5
%13 = and i1 %11, %12
br i1 %13, label %14, label %48
14: ; preds = %4
%15 = bitcast i8* %2 to i32*
br label %16
16: ; preds = %14, %39
%17 = phi i8* [ %44, %39 ], [ %0, %14 ]
%18 = phi i32* [ %19, %39 ], [ %15, %14 ]
%19 = getelementptr inbounds i32, i32* %18, i64 1
%20 = load i32, i32* %18
%21 = add i32 %20, -32
%22 = icmp ult i32 %21, 95
%23 = icmp ne i32 %20, 92
%24 = and i1 %23, %22
br i1 %24, label %39, label %25
25: ; preds = %16
%26 = getelementptr inbounds i8, i8* %17, i64 1
store i8 92, i8* %17
%27 = getelementptr inbounds i8, i8* %17, i64 2
store i8 120, i8* %26
%28 = lshr i32 %20, 4
%29 = icmp slt i32 %20, 160
%30 = select i1 %29, i32 48, i32 87
%31 = add nuw nsw i32 %30, %28
%32 = trunc i32 %31 to i8
%33 = getelementptr inbounds i8, i8* %17, i64 3
store i8 %32, i8* %27
%34 = and i32 %20, 15
%35 = icmp ult i32 %34, 10
%36 = or i32 %34, 48
%37 = add nuw nsw i32 %34, 87
%38 = select i1 %35, i32 %36, i32 %37
br label %39
39: ; preds = %16, %25
%40 = phi i32 [ %38, %25 ], [ %20, %16 ]
%41 = phi i64 [ 4, %25 ], [ 1, %16 ]
%42 = phi i8* [ %33, %25 ], [ %17, %16 ]
%43 = trunc i32 %40 to i8
%44 = getelementptr inbounds i8, i8* %17, i64 %41
store i8 %43, i8* %42
%45 = icmp ult i32* %19, %10
%46 = icmp ult i8* %44, %7
%47 = select i1 %45, i1 %46, i1 false
br i1 %47, label %16, label %48
48: ; preds = %39, %4
%49 = phi i8* [ %0, %4 ], [ %44, %39 ]
store i8 0, i8* %49
ret i8* %0
}