#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 rev_byte_bits(unsigned char);
unsigned short comp_ds90_id(unsigned short ident, int func) {
  unsigned short mask, newid;
  unsigned char idlo, idhi, id1lo, id1hi;
  mask = (ident > 0xffu) ? 0xffffu : 0x00ffu;
  idlo = rev_byte_bits(ident & 0x00ffu);
  idhi = rev_byte_bits((ident & 0xff00u & mask) >> 8);
  ident = rev_byte_bits(ident & 0xffu);
  if (func == 1) {
    id1hi = ((idhi + 0x0001u) & 0x00ffu) & (mask >> 8);
    id1lo = ((idlo + 0x0001u) & 0x00ffu);
  } else {
    id1hi = ((idhi - 0x0001u) & 0x00ffu) & (mask >> 8);
    id1lo = ((idlo - 0x0001u) & 0x00ffu);
  }
  newid = (rev_byte_bits(id1hi) << 8) | rev_byte_bits(id1lo);
  return newid;
}


x86 assembly (clang, -O0):
<comp_ds90_id>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %di,%ax
mov    %ax,-0x2(%rbp)
mov    %esi,-0x8(%rbp)
movzwl -0x2(%rbp),%edx
mov    $0xff,%eax
mov    $0xffff,%ecx
cmp    $0xff,%edx
cmova  %ecx,%eax
mov    %ax,-0xa(%rbp)
movzwl -0x2(%rbp),%eax
and    $0xff,%eax
movzbl %al,%edi
call   1030 <rev_byte_bits@plt>
mov    %al,-0xd(%rbp)
movzwl -0x2(%rbp),%eax
and    $0xff00,%eax
movzwl -0xa(%rbp),%ecx
and    %ecx,%eax
shr    $0x8,%eax
movzbl %al,%edi
call   1030 <rev_byte_bits@plt>
mov    %al,-0xe(%rbp)
movzwl -0x2(%rbp),%eax
and    $0xff,%eax
movzbl %al,%edi
call   1030 <rev_byte_bits@plt>
mov    %ax,-0x2(%rbp)
cmpl   $0x1,-0x8(%rbp)
jne    11b9 <comp_ds90_id+0xa9>
movzbl -0xe(%rbp),%eax
add    $0x1,%eax
and    $0xff,%eax
movzwl -0xa(%rbp),%ecx
sar    $0x8,%ecx
and    %ecx,%eax
mov    %al,-0x10(%rbp)
movzbl -0xd(%rbp),%eax
add    $0x1,%eax
and    $0xff,%eax
mov    %al,-0xf(%rbp)
jmp    11e0 <comp_ds90_id+0xd0>
movzbl -0xe(%rbp),%eax
sub    $0x1,%eax
and    $0xff,%eax
movzwl -0xa(%rbp),%ecx
sar    $0x8,%ecx
and    %ecx,%eax
mov    %al,-0x10(%rbp)
movzbl -0xd(%rbp),%eax
sub    $0x1,%eax
and    $0xff,%eax
mov    %al,-0xf(%rbp)
movzbl -0x10(%rbp),%edi
call   1030 <rev_byte_bits@plt>
shl    $0x8,%eax
mov    %eax,-0x14(%rbp)
movzbl -0xf(%rbp),%edi
call   1030 <rev_byte_bits@plt>
mov    %eax,%ecx
mov    -0x14(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0xc(%rbp)
movzwl -0xc(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<comp_ds90_id>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %esi,%r14d
mov    %edi,%ebp
cmp    $0x100,%edi
mov    $0xffff,%ebx
mov    $0xff,%r13d
cmovb  %r13d,%ebx
movzbl %bpl,%r12d
mov    %r12d,%edi
call   1030 <rev_byte_bits@plt>
mov    %eax,%r15d
and    %ebx,%ebp
shr    $0x8,%ebp
mov    %ebp,%edi
call   1030 <rev_byte_bits@plt>
mov    %eax,%ebp
mov    %r12d,%edi
call   1030 <rev_byte_bits@plt>
cmp    $0x1,%r14d
sete   %al
cmove  %r14d,%r13d
add    %al,%al
add    %al,%r15b
add    %ebp,%r13d
shr    $0x8,%ebx
and    %r13d,%ebx
add    $0xff,%r15b
mov    %ebx,%edi
call   1030 <rev_byte_bits@plt>
mov    %eax,%ebx
shl    $0x8,%ebx
movzbl %r15b,%edi
call   1030 <rev_byte_bits@plt>
or     %ebx,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define zeroext i16 @comp_ds90_id(i16 zeroext %0, i32 %1) {
%3 = alloca i16
%4 = alloca i32
%5 = alloca i16
%6 = alloca i16
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8
store i16 %0, i16* %3
store i32 %1, i32* %4
%11 = load i16, i16* %3
%12 = zext i16 %11 to i32
%13 = icmp ugt i32 %12, 255
%14 = zext i1 %13 to i64
%15 = select i1 %13, i32 65535, i32 255
%16 = trunc i32 %15 to i16
store i16 %16, i16* %5
%17 = load i16, i16* %3
%18 = zext i16 %17 to i32
%19 = and i32 %18, 255
%20 = trunc i32 %19 to i8
%21 = call i32 @rev_byte_bits(i8 zeroext %20)
%22 = trunc i32 %21 to i8
store i8 %22, i8* %7
%23 = load i16, i16* %3
%24 = zext i16 %23 to i32
%25 = and i32 %24, 65280
%26 = load i16, i16* %5
%27 = zext i16 %26 to i32
%28 = and i32 %25, %27
%29 = lshr i32 %28, 8
%30 = trunc i32 %29 to i8
%31 = call i32 @rev_byte_bits(i8 zeroext %30)
%32 = trunc i32 %31 to i8
store i8 %32, i8* %8
%33 = load i16, i16* %3
%34 = zext i16 %33 to i32
%35 = and i32 %34, 255
%36 = trunc i32 %35 to i8
%37 = call i32 @rev_byte_bits(i8 zeroext %36)
%38 = trunc i32 %37 to i16
store i16 %38, i16* %3
%39 = load i32, i32* %4
%40 = icmp eq i32 %39, 1
br i1 %40, label %41, label %56
41: ; preds = %2
%42 = load i8, i8* %8
%43 = zext i8 %42 to i32
%44 = add i32 %43, 1
%45 = and i32 %44, 255
%46 = load i16, i16* %5
%47 = zext i16 %46 to i32
%48 = ashr i32 %47, 8
%49 = and i32 %45, %48
%50 = trunc i32 %49 to i8
store i8 %50, i8* %10
%51 = load i8, i8* %7
%52 = zext i8 %51 to i32
%53 = add i32 %52, 1
%54 = and i32 %53, 255
%55 = trunc i32 %54 to i8
store i8 %55, i8* %9
br label %71
56: ; preds = %2
%57 = load i8, i8* %8
%58 = zext i8 %57 to i32
%59 = sub i32 %58, 1
%60 = and i32 %59, 255
%61 = load i16, i16* %5
%62 = zext i16 %61 to i32
%63 = ashr i32 %62, 8
%64 = and i32 %60, %63
%65 = trunc i32 %64 to i8
store i8 %65, i8* %10
%66 = load i8, i8* %7
%67 = zext i8 %66 to i32
%68 = sub i32 %67, 1
%69 = and i32 %68, 255
%70 = trunc i32 %69 to i8
store i8 %70, i8* %9
br label %71
71: ; preds = %56, %41
%72 = load i8, i8* %10
%73 = call i32 @rev_byte_bits(i8 zeroext %72)
%74 = shl i32 %73, 8
%75 = load i8, i8* %9
%76 = call i32 @rev_byte_bits(i8 zeroext %75)
%77 = or i32 %74, %76
%78 = trunc i32 %77 to i16
store i16 %78, i16* %6
%79 = load i16, i16* %6
ret i16 %79
}

LLVM IR (-O2):
define zeroext i16 @comp_ds90_id(i16 zeroext %0, i32 %1) {
%3 = icmp ugt i16 %0, 255
%4 = select i1 %3, i32 65535, i32 255
%5 = trunc i16 %0 to i8
%6 = tail call i32 @rev_byte_bits(i8 zeroext %5)
%7 = zext i16 %0 to i32
%8 = and i32 %4, %7
%9 = lshr i32 %8, 8
%10 = trunc i32 %9 to i8
%11 = tail call i32 @rev_byte_bits(i8 zeroext %10)
%12 = tail call i32 @rev_byte_bits(i8 zeroext %5)
%13 = icmp eq i32 %1, 1
%14 = select i1 %13, i32 1, i32 255
%15 = select i1 %13, i8 1, i8 -1
%16 = add i32 %11, %14
%17 = lshr i32 %4, 8
%18 = and i32 %16, %17
%19 = trunc i32 %6 to i8
%20 = add i8 %15, %19
%21 = trunc i32 %18 to i8
%22 = tail call i32 @rev_byte_bits(i8 zeroext %21)
%23 = shl i32 %22, 8
%24 = tail call i32 @rev_byte_bits(i8 zeroext %20)
%25 = or i32 %23, %24
%26 = trunc i32 %25 to i16
ret i16 %26
}