#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 tnext;
typedef int tcurr;
typedef int snext;
typedef int scurr;
typedef int int32_t;

/* Variables and functions */
__attribute__((always_)) void tclod_4x17_to_15(int32_t scurr, int32_t snext,
                                               int32_t tcurr, int32_t tnext,
                                               int32_t previous, int32_t *lod) {
  int dels = (((snext) & ((1 << 17) - 1)) | -((snext) & (1 << (17 - 1)))) -
             (((scurr) & ((1 << 17) - 1)) | -((scurr) & (1 << (17 - 1))));
  if (dels & 0x20000)
    dels = ~dels & 0x1ffff;
  int delt = (((tnext) & ((1 << 17) - 1)) | -((tnext) & (1 << (17 - 1)))) -
             (((tcurr) & ((1 << 17) - 1)) | -((tcurr) & (1 << (17 - 1))));
  if (delt & 0x20000)
    delt = ~delt & 0x1ffff;
  dels = (dels > delt) ? dels : delt;
  dels = (previous > dels) ? previous : dels;
  *lod = dels & 0x7fff;
  if (dels & 0x1c000)
    *lod |= 0x4000;
}


x86 assembly (clang, -O0):
<tclod_4x17_to_15>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    %r8d,-0x14(%rbp)
mov    %r9,-0x20(%rbp)
mov    -0x8(%rbp),%eax
and    $0x1ffff,%eax
mov    -0x8(%rbp),%edx
and    $0x10000,%edx
xor    %ecx,%ecx
sub    %edx,%ecx
or     %ecx,%eax
mov    -0x4(%rbp),%ecx
and    $0x1ffff,%ecx
mov    -0x4(%rbp),%esi
and    $0x10000,%esi
xor    %edx,%edx
sub    %esi,%edx
or     %edx,%ecx
sub    %ecx,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
and    $0x20000,%eax
cmp    $0x0,%eax
je     116b <tclod_4x17_to_15+0x6b>
mov    -0x24(%rbp),%eax
xor    $0xffffffff,%eax
and    $0x1ffff,%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%eax
and    $0x1ffff,%eax
mov    -0x10(%rbp),%edx
and    $0x10000,%edx
xor    %ecx,%ecx
sub    %edx,%ecx
or     %ecx,%eax
mov    -0xc(%rbp),%ecx
and    $0x1ffff,%ecx
mov    -0xc(%rbp),%esi
and    $0x10000,%esi
xor    %edx,%edx
sub    %esi,%edx
or     %edx,%ecx
sub    %ecx,%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
and    $0x20000,%eax
cmp    $0x0,%eax
je     11be <tclod_4x17_to_15+0xbe>
mov    -0x28(%rbp),%eax
xor    $0xffffffff,%eax
and    $0x1ffff,%eax
mov    %eax,-0x28(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x28(%rbp),%eax
jle    11d5 <tclod_4x17_to_15+0xd5>
mov    -0x24(%rbp),%eax
mov    %eax,-0x2c(%rbp)
jmp    11db <tclod_4x17_to_15+0xdb>
mov    -0x28(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x24(%rbp),%eax
jle    11f8 <tclod_4x17_to_15+0xf8>
mov    -0x14(%rbp),%eax
mov    %eax,-0x30(%rbp)
jmp    11fe <tclod_4x17_to_15+0xfe>
mov    -0x24(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%ecx
and    $0x7fff,%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x24(%rbp),%eax
and    $0x1c000,%eax
cmp    $0x0,%eax
je     1232 <tclod_4x17_to_15+0x132>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
or     $0x4000,%ecx
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<tclod_4x17_to_15>:
movd   %ecx,%xmm0
movd   %esi,%xmm1
punpckldq %xmm0,%xmm1
movdqa 0xeec(%rip),%xmm0
movdqa %xmm1,%xmm2
pand   %xmm0,%xmm2
movdqa 0xeec(%rip),%xmm3
pand   %xmm3,%xmm1
pxor   %xmm4,%xmm4
pxor   %xmm5,%xmm5
psubd  %xmm1,%xmm5
por    %xmm2,%xmm5
movd   %edx,%xmm1
movd   %edi,%xmm2
punpckldq %xmm1,%xmm2
movdqa %xmm2,%xmm1
pand   %xmm0,%xmm1
pand   %xmm3,%xmm2
pxor   %xmm3,%xmm3
psubd  %xmm2,%xmm3
por    %xmm1,%xmm3
psubd  %xmm3,%xmm5
movdqa 0xeb8(%rip),%xmm1
pand   %xmm5,%xmm1
pcmpeqd %xmm4,%xmm1
pcmpeqd %xmm2,%xmm2
pxor   %xmm1,%xmm2
pand   %xmm5,%xmm1
pandn  %xmm2,%xmm5
pand   %xmm0,%xmm5
por    %xmm1,%xmm5
movd   %xmm5,%eax
pshufd $0x55,%xmm5,%xmm0
movd   %xmm0,%ecx
cmp    %ecx,%eax
cmovg  %eax,%ecx
cmp    %r8d,%ecx
cmovl  %r8d,%ecx
mov    %ecx,%eax
and    $0x7fff,%eax
mov    %eax,%edx
or     $0x4000,%edx
test   $0x1c000,%ecx
cmove  %eax,%edx
mov    %edx,(%r9)
ret

LLVM IR (-O0):
define void @tclod_4x17_to_15(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32* %5) {
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32*
%13 = alloca i32
%14 = alloca i32
store i32 %0, i32* %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store i32 %3, i32* %10
store i32 %4, i32* %11
store i32* %5, i32** %12
%15 = load i32, i32* %8
%16 = and i32 %15, 131071
%17 = load i32, i32* %8
%18 = and i32 %17, 65536
%19 = sub nsw i32 0, %18
%20 = or i32 %16, %19
%21 = load i32, i32* %7
%22 = and i32 %21, 131071
%23 = load i32, i32* %7
%24 = and i32 %23, 65536
%25 = sub nsw i32 0, %24
%26 = or i32 %22, %25
%27 = sub nsw i32 %20, %26
store i32 %27, i32* %13
%28 = load i32, i32* %13
%29 = and i32 %28, 131072
%30 = icmp ne i32 %29, 0
br i1 %30, label %31, label %35
31: ; preds = %6
%32 = load i32, i32* %13
%33 = xor i32 %32, -1
%34 = and i32 %33, 131071
store i32 %34, i32* %13
br label %35
35: ; preds = %31, %6
%36 = load i32, i32* %10
%37 = and i32 %36, 131071
%38 = load i32, i32* %10
%39 = and i32 %38, 65536
%40 = sub nsw i32 0, %39
%41 = or i32 %37, %40
%42 = load i32, i32* %9
%43 = and i32 %42, 131071
%44 = load i32, i32* %9
%45 = and i32 %44, 65536
%46 = sub nsw i32 0, %45
%47 = or i32 %43, %46
%48 = sub nsw i32 %41, %47
store i32 %48, i32* %14
%49 = load i32, i32* %14
%50 = and i32 %49, 131072
%51 = icmp ne i32 %50, 0
br i1 %51, label %52, label %56
52: ; preds = %35
%53 = load i32, i32* %14
%54 = xor i32 %53, -1
%55 = and i32 %54, 131071
store i32 %55, i32* %14
br label %56
56: ; preds = %52, %35
%57 = load i32, i32* %13
%58 = load i32, i32* %14
%59 = icmp sgt i32 %57, %58
br i1 %59, label %60, label %62
60: ; preds = %56
%61 = load i32, i32* %13
br label %64
62: ; preds = %56
%63 = load i32, i32* %14
br label %64
64: ; preds = %62, %60
%65 = phi i32 [ %61, %60 ], [ %63, %62 ]
store i32 %65, i32* %13
%66 = load i32, i32* %11
%67 = load i32, i32* %13
%68 = icmp sgt i32 %66, %67
br i1 %68, label %69, label %71
69: ; preds = %64
%70 = load i32, i32* %11
br label %73
71: ; preds = %64
%72 = load i32, i32* %13
br label %73
73: ; preds = %71, %69
%74 = phi i32 [ %70, %69 ], [ %72, %71 ]
store i32 %74, i32* %13
%75 = load i32, i32* %13
%76 = and i32 %75, 32767
%77 = load i32*, i32** %12
store i32 %76, i32* %77
%78 = load i32, i32* %13
%79 = and i32 %78, 114688
%80 = icmp ne i32 %79, 0
br i1 %80, label %81, label %85
81: ; preds = %73
%82 = load i32*, i32** %12
%83 = load i32, i32* %82
%84 = or i32 %83, 16384
store i32 %84, i32* %82
br label %85
85: ; preds = %81, %73
ret void
}

LLVM IR (-O2):
define void @tclod_4x17_to_15(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32* nocapture writeonly %5) {
%7 = insertelement <2 x i32> poison, i32 %1, i64 0
%8 = insertelement <2 x i32> %7, i32 %3, i64 1
%9 = and <2 x i32> %8, <i32 131071, i32 131071>
%10 = and <2 x i32> %8, <i32 65536, i32 65536>
%11 = sub nsw <2 x i32> zeroinitializer, %10
%12 = or <2 x i32> %9, %11
%13 = insertelement <2 x i32> poison, i32 %0, i64 0
%14 = insertelement <2 x i32> %13, i32 %2, i64 1
%15 = and <2 x i32> %14, <i32 131071, i32 131071>
%16 = and <2 x i32> %14, <i32 65536, i32 65536>
%17 = sub nsw <2 x i32> zeroinitializer, %16
%18 = or <2 x i32> %15, %17
%19 = sub nsw <2 x i32> %12, %18
%20 = and <2 x i32> %19, <i32 131072, i32 131072>
%21 = icmp eq <2 x i32> %20, zeroinitializer
%22 = and <2 x i32> %19, <i32 131071, i32 131071>
%23 = xor <2 x i32> %22, <i32 131071, i32 131071>
%24 = select <2 x i1> %21, <2 x i32> %19, <2 x i32> %23
%25 = extractelement <2 x i32> %24, i64 0
%26 = extractelement <2 x i32> %24, i64 1
%27 = icmp sgt i32 %25, %26
%28 = select i1 %27, i32 %25, i32 %26
%29 = icmp slt i32 %28, %4
%30 = select i1 %29, i32 %4, i32 %28
%31 = and i32 %30, 32767
%32 = and i32 %30, 114688
%33 = icmp eq i32 %32, 0
%34 = or i32 %31, 16384
%35 = select i1 %33, i32 %31, i32 %34
store i32 %35, i32* %5
ret void
}