#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 /*<<< orphan*/ assert(int);
scalar_t__ memchr(unsigned char *, int, size_t);
unsigned char *jbg_next_pscdms(unsigned char *p, size_t len) {
  unsigned char *pp;
  unsigned long l;
  if (len < 2)
    return NULL;
  if (p[0] != 0xff || p[1] == 0x00) {
    do {
      while (p[0] == 0xff && p[1] == 0x00) {
        p += 2;
        len -= 2;
        if (len < 2)
          return NULL;
      }
      assert(len >= 2);
      pp = (unsigned char *)memchr(p, 0xff, len - 1);
      if (!pp)
        return NULL;
      l = pp - p;
      assert(l < len);
      p += l;
      len -= l;
    } while (p[1] == 0x00);
  } else {
    switch (p[1]) {
    case 0x02:
    case 0x03:
    case 0x04:
      return p + 2;
    case 0x05:
      if (len < 6)
        return NULL;
      return p + 6;
    case 0x06:
      if (len < 8)
        return NULL;
      return p + 8;
    case 0x07:
      if (len < 6)
        return NULL;
      l = (((long)p[2] << 24) | ((long)p[3] << 16) | ((long)p[4] << 8) |
           (long)p[5]);
      if (len - 6 < l)
        return NULL;
      return p + 6 + l;
    default:
      return NULL;
    }
  }
  return p;
}


x86 assembly (clang, -O0):
<jbg_next_pscdms>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
cmpq   $0x2,-0x18(%rbp)
jae    1148 <jbg_next_pscdms+0x28>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xff,%eax
jne    116b <jbg_next_pscdms+0x4b>
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%eax
cmp    $0x0,%eax
jne    127c <jbg_next_pscdms+0x15c>
jmp    1170 <jbg_next_pscdms+0x50>
jmp    1175 <jbg_next_pscdms+0x55>
mov    -0x10(%rbp),%rax
movzbl (%rax),%ecx
xor    %eax,%eax
cmp    $0xff,%ecx
mov    %al,-0x29(%rbp)
jne    119e <jbg_next_pscdms+0x7e>
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%eax
cmp    $0x0,%eax
sete   %al
mov    %al,-0x29(%rbp)
mov    -0x29(%rbp),%al
test   $0x1,%al
jne    11ae <jbg_next_pscdms+0x8e>
jmp    11e3 <jbg_next_pscdms+0xc3>
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
sub    $0x2,%rax
mov    %rax,-0x18(%rbp)
cmpq   $0x2,-0x18(%rbp)
jae    11de <jbg_next_pscdms+0xbe>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
jmp    1175 <jbg_next_pscdms+0x55>
cmpq   $0x2,-0x18(%rbp)
setae  %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rdx
sub    $0x1,%rdx
mov    $0xff,%esi
call   1030 <memchr@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    1227 <jbg_next_pscdms+0x107>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x20(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
setb   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
mov    -0x28(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x28(%rbp),%rcx
mov    -0x18(%rbp),%rax
sub    %rcx,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%eax
cmp    $0x0,%eax
je     1170 <jbg_next_pscdms+0x50>
jmp    139f <jbg_next_pscdms+0x27f>
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%eax
add    $0xfffffffe,%eax
mov    %eax,%ecx
mov    %rcx,-0x38(%rbp)
sub    $0x5,%eax
ja     1392 <jbg_next_pscdms+0x272>
mov    -0x38(%rbp),%rax
lea    0xd5f(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
cmpq   $0x6,-0x18(%rbp)
jae    12d3 <jbg_next_pscdms+0x1b3>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
add    $0x6,%rax
mov    %rax,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
cmpq   $0x8,-0x18(%rbp)
jae    12fc <jbg_next_pscdms+0x1dc>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
cmpq   $0x6,-0x18(%rbp)
jae    1325 <jbg_next_pscdms+0x205>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
movzbl 0x2(%rax),%eax
shl    $0x18,%rax
mov    -0x10(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
shl    $0x10,%rcx
or     %rcx,%rax
mov    -0x10(%rbp),%rcx
movzbl 0x4(%rcx),%ecx
shl    $0x8,%rcx
or     %rcx,%rax
mov    -0x10(%rbp),%rcx
movzbl 0x5(%rcx),%ecx
or     %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
sub    $0x6,%rax
cmp    -0x28(%rbp),%rax
jae    137d <jbg_next_pscdms+0x25d>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
add    $0x6,%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
movq   $0x0,-0x8(%rbp)
jmp    13a7 <jbg_next_pscdms+0x287>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<jbg_next_pscdms>:
push   %r15
push   %r14
push   %rbx
cmp    $0x2,%rsi
jae    1136 <jbg_next_pscdms+0x16>
xor    %ebx,%ebx
mov    %rbx,%rax
pop    %rbx
pop    %r14
pop    %r15
ret
mov    %rsi,%r15
mov    %rdi,%r14
cmpb   $0xff,(%rdi)
jne    1180 <jbg_next_pscdms+0x60>
movzbl 0x1(%r14),%eax
xor    %ebx,%ebx
cmp    $0x7,%rax
ja     112d <jbg_next_pscdms+0xd>
lea    0xeab(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
add    $0x2,%r14
mov    %r14,%rbx
jmp    112d <jbg_next_pscdms+0xd>
add    $0x2,%r14
add    $0xfffffffffffffffe,%r15
cmp    $0x2,%r15
jb     112b <jbg_next_pscdms+0xb>
cs nopw 0x0(%rax,%rax,1)
nop
cmpb   $0xff,(%r14)
jne    118d <jbg_next_pscdms+0x6d>
cmpb   $0x0,0x1(%r14)
je     1167 <jbg_next_pscdms+0x47>
xor    %edi,%edi
cmp    $0x2,%r15
setae  %dil
call   1040 <assert@plt>
lea    -0x1(%r15),%rdx
mov    %r14,%rdi
mov    $0xff,%esi
call   1030 <memchr@plt>
test   %rax,%rax
je     112b <jbg_next_pscdms+0xb>
mov    %rax,%rbx
sub    %r14,%rax
xor    %edi,%edi
sub    %rax,%r15
seta   %dil
call   1040 <assert@plt>
cmpb   $0x0,0x1(%rbx)
mov    %rbx,%r14
je     1180 <jbg_next_pscdms+0x60>
jmp    112d <jbg_next_pscdms+0xd>
add    $0x8,%r14
xor    %ebx,%ebx
cmp    $0x8,%r15
cmovae %r14,%rbx
jmp    112d <jbg_next_pscdms+0xd>
cmp    $0x6,%r15
jb     112b <jbg_next_pscdms+0xb>
mov    0x2(%r14),%eax
shl    $0x20,%rax
bswap  %rax
add    $0xfffffffffffffffa,%r15
cmp    %rax,%r15
jb     112b <jbg_next_pscdms+0xb>
lea    (%r14,%rax,1),%rbx
add    $0x6,%rbx
jmp    112d <jbg_next_pscdms+0xd>
add    $0x6,%r14
xor    %ebx,%ebx
cmp    $0x6,%r15
cmovae %r14,%rbx
jmp    112d <jbg_next_pscdms+0xd>

LLVM IR (-O0):
define i8* @jbg_next_pscdms(i8* %0, i64 %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i8*
%7 = alloca i64
store i8* %0, i8** %4
store i64 %1, i64* %5
%8 = load i64, i64* %5
%9 = icmp ult i64 %8, 2
br i1 %9, label %10, label %11
10: ; preds = %2
store i8* null, i8** %3
br label %147
11: ; preds = %2
%12 = load i8*, i8** %4
%13 = getelementptr inbounds i8, i8* %12, i64 0
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
%16 = icmp ne i32 %15, 255
br i1 %16, label %23, label %17
17: ; preds = %11
%18 = load i8*, i8** %4
%19 = getelementptr inbounds i8, i8* %18, i64 1
%20 = load i8, i8* %19
%21 = zext i8 %20 to i32
%22 = icmp eq i32 %21, 0
br i1 %22, label %23, label %85
23: ; preds = %17, %11
br label %24
24: ; preds = %78, %23
br label %25
25: ; preds = %47, %24
%26 = load i8*, i8** %4
%27 = getelementptr inbounds i8, i8* %26, i64 0
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = icmp eq i32 %29, 255
br i1 %30, label %31, label %37
31: ; preds = %25
%32 = load i8*, i8** %4
%33 = getelementptr inbounds i8, i8* %32, i64 1
%34 = load i8, i8* %33
%35 = zext i8 %34 to i32
%36 = icmp eq i32 %35, 0
br label %37
37: ; preds = %31, %25
%38 = phi i1 [ false, %25 ], [ %36, %31 ]
br i1 %38, label %39, label %48
39: ; preds = %37
%40 = load i8*, i8** %4
%41 = getelementptr inbounds i8, i8* %40, i64 2
store i8* %41, i8** %4
%42 = load i64, i64* %5
%43 = sub i64 %42, 2
store i64 %43, i64* %5
%44 = load i64, i64* %5
%45 = icmp ult i64 %44, 2
br i1 %45, label %46, label %47
46: ; preds = %39
store i8* null, i8** %3
br label %147
47: ; preds = %39
br label %25
48: ; preds = %37
%49 = load i64, i64* %5
%50 = icmp uge i64 %49, 2
%51 = zext i1 %50 to i32
%52 = call i32 @assert(i32 %51)
%53 = load i8*, i8** %4
%54 = load i64, i64* %5
%55 = sub i64 %54, 1
%56 = call i64 @memchr(i8* %53, i32 255, i64 %55)
%57 = inttoptr i64 %56 to i8*
store i8* %57, i8** %6
%58 = load i8*, i8** %6
%59 = icmp ne i8* %58, null
br i1 %59, label %61, label %60
60: ; preds = %48
store i8* null, i8** %3
br label %147
61: ; preds = %48
%62 = load i8*, i8** %6
%63 = load i8*, i8** %4
%64 = ptrtoint i8* %62 to i64
%65 = ptrtoint i8* %63 to i64
%66 = sub i64 %64, %65
store i64 %66, i64* %7
%67 = load i64, i64* %7
%68 = load i64, i64* %5
%69 = icmp ult i64 %67, %68
%70 = zext i1 %69 to i32
%71 = call i32 @assert(i32 %70)
%72 = load i64, i64* %7
%73 = load i8*, i8** %4
%74 = getelementptr inbounds i8, i8* %73, i64 %72
store i8* %74, i8** %4
%75 = load i64, i64* %7
%76 = load i64, i64* %5
%77 = sub i64 %76, %75
store i64 %77, i64* %5
br label %78
78: ; preds = %61
%79 = load i8*, i8** %4
%80 = getelementptr inbounds i8, i8* %79, i64 1
%81 = load i8, i8* %80
%82 = zext i8 %81 to i32
%83 = icmp eq i32 %82, 0
br i1 %83, label %24, label %84
84: ; preds = %78
br label %145
85: ; preds = %17
%86 = load i8*, i8** %4
%87 = getelementptr inbounds i8, i8* %86, i64 1
%88 = load i8, i8* %87
%89 = zext i8 %88 to i32
switch i32 %89, label %144 [
i32 2, label %90
i32 3, label %90
i32 4, label %90
i32 5, label %93
i32 6, label %100
i32 7, label %107
]
90: ; preds = %85, %85, %85
%91 = load i8*, i8** %4
%92 = getelementptr inbounds i8, i8* %91, i64 2
store i8* %92, i8** %3
br label %147
93: ; preds = %85
%94 = load i64, i64* %5
%95 = icmp ult i64 %94, 6
br i1 %95, label %96, label %97
96: ; preds = %93
store i8* null, i8** %3
br label %147
97: ; preds = %93
%98 = load i8*, i8** %4
%99 = getelementptr inbounds i8, i8* %98, i64 6
store i8* %99, i8** %3
br label %147
100: ; preds = %85
%101 = load i64, i64* %5
%102 = icmp ult i64 %101, 8
br i1 %102, label %103, label %104
103: ; preds = %100
store i8* null, i8** %3
br label %147
104: ; preds = %100
%105 = load i8*, i8** %4
%106 = getelementptr inbounds i8, i8* %105, i64 8
store i8* %106, i8** %3
br label %147
107: ; preds = %85
%108 = load i64, i64* %5
%109 = icmp ult i64 %108, 6
br i1 %109, label %110, label %111
110: ; preds = %107
store i8* null, i8** %3
br label %147
111: ; preds = %107
%112 = load i8*, i8** %4
%113 = getelementptr inbounds i8, i8* %112, i64 2
%114 = load i8, i8* %113
%115 = zext i8 %114 to i64
%116 = shl i64 %115, 24
%117 = load i8*, i8** %4
%118 = getelementptr inbounds i8, i8* %117, i64 3
%119 = load i8, i8* %118
%120 = zext i8 %119 to i64
%121 = shl i64 %120, 16
%122 = or i64 %116, %121
%123 = load i8*, i8** %4
%124 = getelementptr inbounds i8, i8* %123, i64 4
%125 = load i8, i8* %124
%126 = zext i8 %125 to i64
%127 = shl i64 %126, 8
%128 = or i64 %122, %127
%129 = load i8*, i8** %4
%130 = getelementptr inbounds i8, i8* %129, i64 5
%131 = load i8, i8* %130
%132 = zext i8 %131 to i64
%133 = or i64 %128, %132
store i64 %133, i64* %7
%134 = load i64, i64* %5
%135 = sub i64 %134, 6
%136 = load i64, i64* %7
%137 = icmp ult i64 %135, %136
br i1 %137, label %138, label %139
138: ; preds = %111
store i8* null, i8** %3
br label %147
139: ; preds = %111
%140 = load i8*, i8** %4
%141 = getelementptr inbounds i8, i8* %140, i64 6
%142 = load i64, i64* %7
%143 = getelementptr inbounds i8, i8* %141, i64 %142
store i8* %143, i8** %3
br label %147
144: ; preds = %85
store i8* null, i8** %3
br label %147
145: ; preds = %84
%146 = load i8*, i8** %4
store i8* %146, i8** %3
br label %147
147: ; preds = %145, %144, %139, %138, %110, %104, %103, %97, %96, %90, %60, %46, %10
%148 = load i8*, i8** %3
ret i8* %148
}

LLVM IR (-O2):
define i8* @jbg_next_pscdms(i8* %0, i64 %1) {
%3 = icmp ult i64 %1, 2
br i1 %3, label %81, label %4
4: ; preds = %2
%5 = load i8, i8* %0
%6 = icmp eq i8 %5, -1
br i1 %6, label %7, label %10
7: ; preds = %4
%8 = getelementptr inbounds i8, i8* %0, i64 1
%9 = load i8, i8* %8
switch i8 %9, label %81 [
i8 0, label %10
i8 2, label %45
i8 3, label %45
i8 4, label %45
i8 5, label %47
i8 6, label %51
i8 7, label %55
]
10: ; preds = %4, %7
br label %11
11: ; preds = %24, %10
%12 = phi i8* [ %0, %10 ], [ %25, %24 ]
%13 = phi i64 [ %1, %10 ], [ %26, %24 ]
%14 = load i8, i8* %12
%15 = icmp eq i8 %14, -1
br i1 %15, label %16, label %27
16: ; preds = %11
%17 = getelementptr inbounds i8, i8* %12, i64 1
%18 = load i8, i8* %17
%19 = icmp eq i8 %18, 0
br i1 %19, label %20, label %27
20: ; preds = %16
%21 = getelementptr inbounds i8, i8* %12, i64 2
%22 = add i64 %13, -2
%23 = icmp ult i64 %22, 2
br i1 %23, label %81, label %24
24: ; preds = %20, %34
%25 = phi i8* [ %21, %20 ], [ %40, %34 ]
%26 = phi i64 [ %22, %20 ], [ %41, %34 ]
br label %11
27: ; preds = %11, %16
%28 = icmp ugt i64 %13, 1
%29 = zext i1 %28 to i32
%30 = tail call i32 @assert(i32 %29)
%31 = add i64 %13, -1
%32 = tail call i64 @memchr(i8* %12, i32 255, i64 %31)
%33 = icmp eq i64 %32, 0
br i1 %33, label %81, label %34
34: ; preds = %27
%35 = ptrtoint i8* %12 to i64
%36 = sub i64 %32, %35
%37 = icmp ugt i64 %13, %36
%38 = zext i1 %37 to i32
%39 = tail call i32 @assert(i32 %38)
%40 = getelementptr inbounds i8, i8* %12, i64 %36
%41 = sub i64 %13, %36
%42 = getelementptr inbounds i8, i8* %40, i64 1
%43 = load i8, i8* %42
%44 = icmp eq i8 %43, 0
br i1 %44, label %24, label %81
45: ; preds = %7, %7, %7
%46 = getelementptr inbounds i8, i8* %0, i64 2
br label %81
47: ; preds = %7
%48 = icmp ult i64 %1, 6
%49 = getelementptr inbounds i8, i8* %0, i64 6
%50 = select i1 %48, i8* null, i8* %49
br label %81
51: ; preds = %7
%52 = icmp ult i64 %1, 8
%53 = getelementptr inbounds i8, i8* %0, i64 8
%54 = select i1 %52, i8* null, i8* %53
br label %81
55: ; preds = %7
%56 = icmp ult i64 %1, 6
br i1 %56, label %81, label %57
57: ; preds = %55
%58 = getelementptr inbounds i8, i8* %0, i64 2
%59 = load i8, i8* %58
%60 = zext i8 %59 to i64
%61 = shl nuw nsw i64 %60, 24
%62 = getelementptr inbounds i8, i8* %0, i64 3
%63 = load i8, i8* %62
%64 = zext i8 %63 to i64
%65 = shl nuw nsw i64 %64, 16
%66 = or i64 %65, %61
%67 = getelementptr inbounds i8, i8* %0, i64 4
%68 = load i8, i8* %67
%69 = zext i8 %68 to i64
%70 = shl nuw nsw i64 %69, 8
%71 = or i64 %66, %70
%72 = getelementptr inbounds i8, i8* %0, i64 5
%73 = load i8, i8* %72
%74 = zext i8 %73 to i64
%75 = or i64 %71, %74
%76 = add i64 %1, -6
%77 = icmp ult i64 %76, %75
br i1 %77, label %81, label %78
78: ; preds = %57
%79 = getelementptr inbounds i8, i8* %0, i64 6
%80 = getelementptr inbounds i8, i8* %79, i64 %75
br label %81
81: ; preds = %34, %27, %20, %51, %47, %7, %57, %55, %2, %78, %45
%82 = phi i8* [ %80, %78 ], [ %46, %45 ], [ null, %2 ], [ null, %55 ], [ null, %57 ], [ null, %7 ], [ %50, %47 ], [ %54, %51 ], [ %40, %34 ], [ null, %27 ], [ null, %20 ]
ret i8* %82
}