void todec(x, y) unsigned short *x, *y;
{
  unsigned short i;
  unsigned short *p;
  p = x;
  *y = 0;
  if (*p++)
    *y = 0100000;
  i = *p++;
  if (i == 0) {
    *y++ = 0;
    *y++ = 0;
    *y++ = 0;
    *y++ = 0;
    return;
  }
  if (i > 0377) {
    *y++ |= 077777;
    *y++ = 0xffff;
    *y++ = 0xffff;
    *y++ = 0xffff;
    return;
  }
  i &= 0377;
  i <<= 7;
  eshup8(x);
  x[2] &= 0177;
  i |= x[2];
  *y++ |= i;
  *y++ = x[2 + 1];
  *y++ = x[2 + 2];
  *y++ = x[2 + 3];
}


x86 assembly (clang, -O0):
<todec>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movw   $0x0,(%rax)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x20(%rbp)
cmpw   $0x0,(%rax)
je     1153 <todec+0x43>
mov    -0x10(%rbp),%rax
movw   $0x8000,(%rax)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%ax
mov    %ax,-0x12(%rbp)
movzwl -0x12(%rbp),%eax
cmp    $0x0,%eax
jne    11cb <todec+0xbb>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0x0,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0x0,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0x0,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0x0,(%rax)
jmp    12e3 <todec+0x1d3>
movzwl -0x12(%rbp),%eax
cmp    $0xff,%eax
jle    1236 <todec+0x126>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movzwl (%rax),%ecx
or     $0x7fff,%ecx
mov    %cx,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0xffff,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0xffff,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movw   $0xffff,(%rax)
jmp    12e3 <todec+0x1d3>
movzwl -0x12(%rbp),%eax
and    $0xff,%eax
mov    %ax,-0x12(%rbp)
movzwl -0x12(%rbp),%eax
shl    $0x7,%eax
mov    %ax,-0x12(%rbp)
mov    -0x8(%rbp),%rdi
mov    $0x0,%al
call   1030 <eshup8@plt>
mov    -0x8(%rbp),%rax
movzwl 0x4(%rax),%ecx
and    $0x7f,%ecx
mov    %cx,0x4(%rax)
mov    -0x8(%rbp),%rax
movzwl 0x4(%rax),%ecx
movzwl -0x12(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x12(%rbp)
movzwl -0x12(%rbp),%edx
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movzwl (%rax),%ecx
or     %edx,%ecx
mov    %cx,(%rax)
mov    -0x8(%rbp),%rax
mov    0x6(%rax),%cx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x2,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cx,(%rax)
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%cx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x2,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cx,(%rax)
mov    -0x8(%rbp),%rax
mov    0xa(%rax),%cx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x2,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cx,(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<todec>:
push   %rbp
push   %r14
push   %rbx
mov    %rsi,%r14
movw   $0x0,(%rsi)
xor    %eax,%eax
cmpw   $0x0,(%rdi)
setne  %al
shl    $0xf,%eax
mov    %ax,(%rsi)
movzwl 0x2(%rdi),%ecx
test   %cx,%cx
je     1159 <todec+0x49>
movzwl %cx,%edx
cmp    $0x100,%edx
jb     1162 <todec+0x52>
or     $0x7fff,%eax
mov    %ax,(%r14)
movl   $0xffffffff,0x2(%r14)
ff
movw   $0xffff,0x6(%r14)
jmp    119e <todec+0x8e>
movq   $0x0,(%r14)
jmp    119e <todec+0x8e>
mov    %rdi,%rbx
movzbl %cl,%ebp
shl    $0x7,%ebp
xor    %eax,%eax
call   1030 <eshup8@plt>
movzwl 0x4(%rbx),%eax
and    $0x7f,%eax
mov    %ax,0x4(%rbx)
or     %ebp,%eax
or     %ax,(%r14)
movzwl 0x6(%rbx),%eax
mov    %ax,0x2(%r14)
movzwl 0x8(%rbx),%eax
mov    %ax,0x4(%r14)
movzwl 0xa(%rbx),%eax
mov    %ax,0x6(%r14)
pop    %rbx
pop    %r14
pop    %rbp
ret

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

LLVM IR (-O2):
define void @todec(i16* %0, i16* nocapture %1) {
store i16 0, i16* %1
%3 = getelementptr inbounds i16, i16* %0, i64 1
%4 = load i16, i16* %0
%5 = icmp eq i16 %4, 0
%6 = select i1 %5, i16 0, i16 -32768
store i16 %6, i16* %1
%7 = load i16, i16* %3
%8 = icmp eq i16 %7, 0
br i1 %8, label %9, label %11
9: ; preds = %2
%10 = bitcast i16* %1 to i64*
store i64 0, i64* %10
br label %37
11: ; preds = %2
%12 = icmp ugt i16 %7, 255
br i1 %12, label %13, label %18
13: ; preds = %11
%14 = getelementptr inbounds i16, i16* %1, i64 1
%15 = or i16 %6, 32767
store i16 %15, i16* %1
%16 = getelementptr inbounds i16, i16* %1, i64 2
store i16 -1, i16* %14
%17 = getelementptr inbounds i16, i16* %1, i64 3
store i16 -1, i16* %16
store i16 -1, i16* %17
br label %37
18: ; preds = %11
%19 = shl nuw nsw i16 %7, 7
%20 = and i16 %19, 32640
%21 = tail call i32 (i16*, ...) bitcast (i32 (...)* @eshup8 to i32 (i16*, ...)*)(i16* %0)
%22 = getelementptr inbounds i16, i16* %0, i64 2
%23 = load i16, i16* %22
%24 = and i16 %23, 127
store i16 %24, i16* %22
%25 = or i16 %24, %20
%26 = getelementptr inbounds i16, i16* %1, i64 1
%27 = load i16, i16* %1
%28 = or i16 %25, %27
store i16 %28, i16* %1
%29 = getelementptr inbounds i16, i16* %0, i64 3
%30 = load i16, i16* %29
%31 = getelementptr inbounds i16, i16* %1, i64 2
store i16 %30, i16* %26
%32 = getelementptr inbounds i16, i16* %0, i64 4
%33 = load i16, i16* %32
%34 = getelementptr inbounds i16, i16* %1, i64 3
store i16 %33, i16* %31
%35 = getelementptr inbounds i16, i16* %0, i64 5
%36 = load i16, i16* %35
store i16 %36, i16* %34
br label %37
37: ; preds = %18, %13, %9
ret void
}