#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 /*<<< orphan*/ wchar_t;
typedef int uint8_t;
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
int /*<<< orphan*/ free(int *);
int /*<<< orphan*/ memcmp(int *, char *, int);
int *pzx_load_block(int /*<<< orphan*/ *);
int /*<<< orphan*/ rewind(int /*<<< orphan*/ *);
int /*<<< orphan*/ swprintf(int /*<<< orphan*/ *, int, char *, int, int);
wchar_t *pzx_check_version(FILE *fp) {
  uint8_t *block;
  static wchar_t message[80];
  rewind(fp);
  while ((block = pzx_load_block(fp))) {
    if (!memcmp(block, "PZXT", 4)) {
      ;
      if (block[8] != 1) {
        swprintf(message, 80, L"Unsupported PZX version %d.%d\n", block[8],
                 block[9]);
        free(block);
        return message;
      }
    }
    free(block);
  }
  rewind(fp);
  return NULL;
}


x86 assembly (clang, -O0):
<pzx_check_version>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <rewind@plt>
mov    -0x10(%rbp),%rdi
call   1070 <pzx_load_block@plt>
mov    %rax,-0x18(%rbp)
cmp    $0x0,%rax
je     11fb <pzx_check_version+0xab>
mov    -0x18(%rbp),%rdi
lea    0xe79(%rip),%rsi
mov    $0x4,%edx
call   1050 <memcmp@plt>
cmp    $0x0,%eax
jne    11ed <pzx_check_version+0x9d>
mov    -0x18(%rbp),%rax
cmpl   $0x1,0x20(%rax)
je     11e8 <pzx_check_version+0x98>
mov    -0x18(%rbp),%rax
mov    0x20(%rax),%ecx
mov    -0x18(%rbp),%rax
mov    0x24(%rax),%r8d
lea    0x2ea2(%rip),%rdi
mov    $0x50,%esi
lea    0xe3e(%rip),%rdx
call   1060 <swprintf@plt>
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
lea    0x2e81(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    120c <pzx_check_version+0xbc>
jmp    11ed <pzx_check_version+0x9d>
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
jmp    1165 <pzx_check_version+0x15>
mov    -0x10(%rbp),%rdi
call   1040 <rewind@plt>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pzx_check_version>:
push   %r15
push   %r14
push   %rbx
mov    %rdi,%r14
call   1040 <rewind@plt>
mov    %r14,%rdi
call   1070 <pzx_load_block@plt>
test   %rax,%rax
je     11dd <pzx_check_version+0x8d>
mov    %rax,%rbx
lea    0xe8c(%rip),%r15
jmp    1198 <pzx_check_version+0x48>
cs nopw 0x0(%rax,%rax,1)
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %r14,%rdi
call   1070 <pzx_load_block@plt>
mov    %rax,%rbx
test   %rax,%rax
je     11dd <pzx_check_version+0x8d>
mov    %rbx,%rdi
mov    %r15,%rsi
mov    $0x4,%edx
call   1050 <memcmp@plt>
test   %eax,%eax
jne    1180 <pzx_check_version+0x30>
mov    0x20(%rbx),%ecx
cmp    $0x1,%ecx
je     1180 <pzx_check_version+0x30>
mov    0x24(%rbx),%r8d
lea    0x2ea1(%rip),%r14
lea    0xe42(%rip),%rdx
mov    %r14,%rdi
mov    $0x50,%esi
call   1060 <swprintf@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
jmp    11e8 <pzx_check_version+0x98>
mov    %r14,%rdi
call   1040 <rewind@plt>
xor    %r14d,%r14d
mov    %r14,%rax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@pzx_check_version.message = internal global [80 x i32] zeroinitializer
@.str = [5 x i8] c"PZXT\00"
@.str.1 = [31 x i32] [i32 85, i32 110, i32 115, i32 117, i32 112, i32 112, i32 111, i32 114, i32 116, i32 101, i32 100, i32 32, i32 80, i32 90, i32 88, i32 32, i32 118, i32 101, i32 114, i32 115, i32 105, i32 111, i32 110, i32 32, i32 37, i32 100, i32 46, i32 37, i32 100, i32 10, i32 0]
define i32* @pzx_check_version(i32* %0) {
%2 = alloca i32*
%3 = alloca i32*
%4 = alloca i32*
store i32* %0, i32** %3
%5 = load i32*, i32** %3
%6 = call i32 @rewind(i32* %5)
br label %7
7: ; preds = %31, %1
%8 = load i32*, i32** %3
%9 = call i32* @pzx_load_block(i32* %8)
store i32* %9, i32** %4
%10 = icmp ne i32* %9, null
br i1 %10, label %11, label %34
11: ; preds = %7
%12 = load i32*, i32** %4
%13 = call i32 @memcmp(i32* %12, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i32 4)
%14 = icmp ne i32 %13, 0
br i1 %14, label %31, label %15
15: ; preds = %11
%16 = load i32*, i32** %4
%17 = getelementptr inbounds i32, i32* %16, i64 8
%18 = load i32, i32* %17
%19 = icmp ne i32 %18, 1
br i1 %19, label %20, label %30
20: ; preds = %15
%21 = load i32*, i32** %4
%22 = getelementptr inbounds i32, i32* %21, i64 8
%23 = load i32, i32* %22
%24 = load i32*, i32** %4
%25 = getelementptr inbounds i32, i32* %24, i64 9
%26 = load i32, i32* %25
%27 = call i32 @swprintf(i32* getelementptr inbounds ([80 x i32], [80 x i32]* @pzx_check_version.message, i64 0, i64 0), i32 80, i8* bitcast ([31 x i32]* @.str.1 to i8*), i32 %23, i32 %26)
%28 = load i32*, i32** %4
%29 = call i32 @free(i32* %28)
store i32* getelementptr inbounds ([80 x i32], [80 x i32]* @pzx_check_version.message, i64 0, i64 0), i32** %2
br label %37
30: ; preds = %15
br label %31
31: ; preds = %30, %11
%32 = load i32*, i32** %4
%33 = call i32 @free(i32* %32)
br label %7
34: ; preds = %7
%35 = load i32*, i32** %3
%36 = call i32 @rewind(i32* %35)
store i32* null, i32** %2
br label %37
37: ; preds = %34, %20
%38 = load i32*, i32** %2
ret i32* %38
}

LLVM IR (-O2):
@pzx_check_version.message = internal global [80 x i32] zeroinitializer
@.str = [5 x i8] c"PZXT\00"
@.str.1 = [31 x i32] [i32 85, i32 110, i32 115, i32 117, i32 112, i32 112, i32 111, i32 114, i32 116, i32 101, i32 100, i32 32, i32 80, i32 90, i32 88, i32 32, i32 118, i32 101, i32 114, i32 115, i32 105, i32 111, i32 110, i32 32, i32 37, i32 100, i32 46, i32 37, i32 100, i32 10, i32 0]
define i32* @pzx_check_version(i32* %0) {
%2 = tail call i32 @rewind(i32* %0)
%3 = tail call i32* @pzx_load_block(i32* %0)
%4 = icmp eq i32* %3, null
br i1 %4, label %22, label %5
5: ; preds = %1, %18
%6 = phi i32* [ %20, %18 ], [ %3, %1 ]
%7 = tail call i32 @memcmp(i32* %6, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i32 4)
%8 = icmp eq i32 %7, 0
br i1 %8, label %9, label %18
9: ; preds = %5
%10 = getelementptr inbounds i32, i32* %6, i64 8
%11 = load i32, i32* %10
%12 = icmp eq i32 %11, 1
br i1 %12, label %18, label %13
13: ; preds = %9
%14 = getelementptr inbounds i32, i32* %6, i64 9
%15 = load i32, i32* %14
%16 = tail call i32 @swprintf(i32* getelementptr inbounds ([80 x i32], [80 x i32]* @pzx_check_version.message, i64 0, i64 0), i32 80, i8* bitcast ([31 x i32]* @.str.1 to i8*), i32 %11, i32 %15)
%17 = tail call i32 @free(i32* %6)
br label %24
18: ; preds = %9, %5
%19 = tail call i32 @free(i32* %6)
%20 = tail call i32* @pzx_load_block(i32* %0)
%21 = icmp eq i32* %20, null
br i1 %21, label %22, label %5
22: ; preds = %18, %1
%23 = tail call i32 @rewind(i32* %0)
br label %24
24: ; preds = %22, %13
%25 = phi i32* [ getelementptr inbounds ([80 x i32], [80 x i32]* @pzx_check_version.message, i64 0, i64 0), %13 ], [ null, %22 ]
ret i32* %25
}