char *ascii85_tuple(char *tuple, unsigned char *data) {
  register long i, x;
  unsigned long code, quantum;
  code = ((((unsigned long)data[0] << 8) | (unsigned long)data[1]) << 16) |
         ((unsigned long)data[2] << 8) | (unsigned long)data[3];
  if (code == 0L) {
    tuple[0] = 'z';
    tuple[1] = '\0';
    return (tuple);
  }
  quantum = 85UL * 85UL * 85UL * 85UL;
  for (i = 0; i < 4; i++) {
    x = (long)(code / quantum);
    code -= quantum * x;
    tuple[i] = (char)(x + (int)'!');
    quantum /= 85L;
  }
  tuple[4] = (char)((code % 85L) + (int)'!');
  tuple[5] = '\0';
  return tuple;
}


x86 assembly (clang, -O0):
<ascii85_tuple>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
shl    $0x8,%rax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
or     %rcx,%rax
shl    $0x10,%rax
mov    -0x18(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
shl    $0x8,%rcx
or     %rcx,%rax
mov    -0x18(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
or     %rcx,%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    116b <ascii85_tuple+0x6b>
mov    -0x10(%rbp),%rax
movb   $0x7a,(%rax)
mov    -0x10(%rbp),%rax
movb   $0x0,0x1(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    120d <ascii85_tuple+0x10d>
movq   $0x31c84b1,-0x38(%rbp)
03
movq   $0x0,-0x20(%rbp)
cmpq   $0x4,-0x20(%rbp)
jge    11e2 <ascii85_tuple+0xe2>
mov    -0x30(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x38(%rbp)
mov    %rax,-0x28(%rbp)
mov    -0x38(%rbp),%rcx
imul   -0x28(%rbp),%rcx
mov    -0x30(%rbp),%rax
sub    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
add    $0x21,%rax
mov    %al,%dl
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
mov    $0x55,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    117b <ascii85_tuple+0x7b>
mov    -0x30(%rbp),%rax
mov    $0x55,%ecx
xor    %edx,%edx
div    %rcx
add    $0x21,%rdx
mov    %dl,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x4(%rax)
mov    -0x10(%rbp),%rax
movb   $0x0,0x5(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ascii85_tuple>:
mov    (%rsi),%eax
shl    $0x20,%rax
bswap  %rax
test   %rax,%rax
je     11c8 <ascii85_tuple+0xc8>
imul   $0x491cc17d,%rax,%rcx
shr    $0x20,%rcx
mov    %eax,%edx
sub    %ecx,%edx
shr    %edx
add    %ecx,%edx
shr    $0x19,%edx
imul   $0xfffffffffce37b4f,%rdx,%rcx
add    %rax,%rcx
add    $0x21,%dl
mov    %dl,(%rdi)
movabs $0xda8d187cb9cfbe87,%rdx
18 8d da
mov    %rcx,%rax
mul    %rdx
shr    $0x13,%rdx
imul   $0xfffffffffff6a113,%rdx,%rsi
add    %rcx,%rsi
add    $0x21,%dl
mov    %dl,0x1(%rdi)
movabs $0x22436485a6c7e90b,%rcx
64 43 22
mov    %rsi,%rax
mul    %rcx
mov    %rsi,%rax
sub    %rdx,%rax
shr    %rax
add    %rdx,%rax
shr    $0xc,%rax
imul   $0xffffffffffffe3c7,%rax,%rcx
add    %rsi,%rcx
add    $0x21,%al
mov    %al,0x2(%rdi)
movabs $0xc0c0c0c0c0c0c0c1,%r8
c0 c0 c0
mov    %rcx,%rax
mul    %r8
shr    $0x6,%rdx
imul   $0xffffffffffffffab,%rdx,%rsi
add    %rcx,%rsi
add    $0x21,%dl
mov    %dl,0x3(%rdi)
mov    %rsi,%rax
mul    %r8
shr    $0x6,%edx
imul   $0x55,%edx,%eax
sub    %eax,%esi
add    $0x21,%sil
mov    %sil,0x4(%rdi)
mov    $0x5,%eax
jmp    11d0 <ascii85_tuple+0xd0>
movb   $0x7a,(%rdi)
mov    $0x1,%eax
movb   $0x0,(%rdi,%rax,1)
mov    %rdi,%rax
ret

LLVM IR (-O0):
define i8* @ascii85_tuple(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
%10 = load i8*, i8** %5
%11 = getelementptr inbounds i8, i8* %10, i64 0
%12 = load i8, i8* %11
%13 = zext i8 %12 to i64
%14 = shl i64 %13, 8
%15 = load i8*, i8** %5
%16 = getelementptr inbounds i8, i8* %15, i64 1
%17 = load i8, i8* %16
%18 = zext i8 %17 to i64
%19 = or i64 %14, %18
%20 = shl i64 %19, 16
%21 = load i8*, i8** %5
%22 = getelementptr inbounds i8, i8* %21, i64 2
%23 = load i8, i8* %22
%24 = zext i8 %23 to i64
%25 = shl i64 %24, 8
%26 = or i64 %20, %25
%27 = load i8*, i8** %5
%28 = getelementptr inbounds i8, i8* %27, i64 3
%29 = load i8, i8* %28
%30 = zext i8 %29 to i64
%31 = or i64 %26, %30
store i64 %31, i64* %8
%32 = load i64, i64* %8
%33 = icmp eq i64 %32, 0
br i1 %33, label %34, label %40
34: ; preds = %2
%35 = load i8*, i8** %4
%36 = getelementptr inbounds i8, i8* %35, i64 0
store i8 122, i8* %36
%37 = load i8*, i8** %4
%38 = getelementptr inbounds i8, i8* %37, i64 1
store i8 0, i8* %38
%39 = load i8*, i8** %4
store i8* %39, i8** %3
br label %74
40: ; preds = %2
store i64 52200625, i64* %9
store i64 0, i64* %6
br label %41
41: ; preds = %61, %40
%42 = load i64, i64* %6
%43 = icmp slt i64 %42, 4
br i1 %43, label %44, label %64
44: ; preds = %41
%45 = load i64, i64* %8
%46 = load i64, i64* %9
%47 = udiv i64 %45, %46
store i64 %47, i64* %7
%48 = load i64, i64* %9
%49 = load i64, i64* %7
%50 = mul i64 %48, %49
%51 = load i64, i64* %8
%52 = sub i64 %51, %50
store i64 %52, i64* %8
%53 = load i64, i64* %7
%54 = add nsw i64 %53, 33
%55 = trunc i64 %54 to i8
%56 = load i8*, i8** %4
%57 = load i64, i64* %6
%58 = getelementptr inbounds i8, i8* %56, i64 %57
store i8 %55, i8* %58
%59 = load i64, i64* %9
%60 = udiv i64 %59, 85
store i64 %60, i64* %9
br label %61
61: ; preds = %44
%62 = load i64, i64* %6
%63 = add nsw i64 %62, 1
store i64 %63, i64* %6
br label %41
64: ; preds = %41
%65 = load i64, i64* %8
%66 = urem i64 %65, 85
%67 = add i64 %66, 33
%68 = trunc i64 %67 to i8
%69 = load i8*, i8** %4
%70 = getelementptr inbounds i8, i8* %69, i64 4
store i8 %68, i8* %70
%71 = load i8*, i8** %4
%72 = getelementptr inbounds i8, i8* %71, i64 5
store i8 0, i8* %72
%73 = load i8*, i8** %4
store i8* %73, i8** %3
br label %74
74: ; preds = %64, %34
%75 = load i8*, i8** %3
ret i8* %75
}

LLVM IR (-O2):
define i8* @ascii85_tuple(i8* returned writeonly %0, i8* nocapture %1) {
%3 = load i8, i8* %1
%4 = zext i8 %3 to i64
%5 = getelementptr inbounds i8, i8* %1, i64 1
%6 = load i8, i8* %5
%7 = zext i8 %6 to i64
%8 = shl nuw nsw i64 %4, 24
%9 = shl nuw nsw i64 %7, 16
%10 = or i64 %9, %8
%11 = getelementptr inbounds i8, i8* %1, i64 2
%12 = load i8, i8* %11
%13 = zext i8 %12 to i64
%14 = shl nuw nsw i64 %13, 8
%15 = or i64 %10, %14
%16 = getelementptr inbounds i8, i8* %1, i64 3
%17 = load i8, i8* %16
%18 = zext i8 %17 to i64
%19 = or i64 %15, %18
%20 = icmp eq i64 %19, 0
br i1 %20, label %49, label %21
21: ; preds = %2
%22 = udiv i64 %19, 52200625
%23 = mul nsw i64 %22, -52200625
%24 = add i64 %23, %19
%25 = trunc i64 %22 to i8
%26 = add i8 %25, 33
store i8 %26, i8* %0
%27 = udiv i64 %24, 614125
%28 = mul i64 %27, -614125
%29 = add i64 %28, %24
%30 = trunc i64 %27 to i8
%31 = add i8 %30, 33
%32 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %31, i8* %32
%33 = udiv i64 %29, 7225
%34 = mul i64 %33, -7225
%35 = add i64 %34, %29
%36 = trunc i64 %33 to i8
%37 = add i8 %36, 33
%38 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %37, i8* %38
%39 = udiv i64 %35, 85
%40 = mul i64 %39, -85
%41 = add i64 %40, %35
%42 = trunc i64 %39 to i8
%43 = add i8 %42, 33
%44 = getelementptr inbounds i8, i8* %0, i64 3
store i8 %43, i8* %44
%45 = urem i64 %41, 85
%46 = trunc i64 %45 to i8
%47 = add nuw nsw i8 %46, 33
%48 = getelementptr inbounds i8, i8* %0, i64 4
store i8 %47, i8* %48
br label %50
49: ; preds = %2
store i8 122, i8* %0
br label %50
50: ; preds = %21, %49
%51 = phi i64 [ 5, %21 ], [ 1, %49 ]
%52 = getelementptr inbounds i8, i8* %0, i64 %51
store i8 0, i8* %52
ret i8* %0
}