#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 */
struct cwio_device {
  int dummy;
};
struct cwio_data {
  int dummy;
};
typedef int /*<<< orphan*/ buffer;

/* Variables and functions */
void *alloca(int /*<<< orphan*/);
int /*<<< orphan*/ cwio_close(struct cwio_device *);
int /*<<< orphan*/ cwio_data_set_params(struct cwio_data *, int,
                                        int /*<<< orphan*/, int, int, int,
                                        unsigned char *, int);
int /*<<< orphan*/ cwio_data_struct_size();
scalar_t__ cwio_device_has_double_step(struct cwio_device *);
int /*<<< orphan*/ cwio_device_set_params(struct cwio_device *, char *, int);
int /*<<< orphan*/ cwio_device_struct_size();
int /*<<< orphan*/ cwio_open(struct cwio_device *, int);
int cwio_read(struct cwio_device *, struct cwio_data *);
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, ...);
int /*<<< orphan*/ fwrite(unsigned char *, int, int, int /*<<< orphan*/);
int /*<<< orphan*/ stderr;
int /*<<< orphan*/ stdout;
int main(void) {
  struct cwio_device *cwio_dev;
  struct cwio_data *cwio_data;
  unsigned char buffer[0x20000];
  int track = 10;
  int len;
  cwio_dev = alloca(cwio_device_struct_size());
  cwio_data = alloca(cwio_data_struct_size());
  if ((cwio_dev == NULL) || (cwio_data == NULL)) {
    fprintf(stderr, "out of memory\n");
    exit(1);
  }
  cwio_device_set_params(cwio_dev, "/dev/cw0raw0", 1);
  cwio_open(cwio_dev, 1);
  if (cwio_device_has_double_step(cwio_dev))
    track /= 2;
  fprintf(stderr, "reading track %d\n", track);
  cwio_data_set_params(cwio_data, track, 0, 1, 1, 400, buffer, sizeof(buffer));
  len = cwio_read(cwio_dev, cwio_data);
  fwrite(buffer, 1, len, stdout);
  cwio_close(cwio_dev);
  return (0);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20040,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0xa,-0x20024(%rbp)
mov    $0x0,%al
call   1060 <cwio_device_struct_size@plt>
mov    %eax,%edi
call   1080 <alloca@plt>
mov    %rax,-0x10(%rbp)
mov    $0x0,%al
call   1030 <cwio_data_struct_size@plt>
mov    %eax,%edi
call   1080 <alloca@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     1216 <main+0x56>
cmpq   $0x0,-0x18(%rbp)
jne    1237 <main+0x77>
mov    0x2dc3(%rip),%rax
mov    (%rax),%edi
lea    0xdda(%rip),%rsi
mov    $0x0,%al
call   1070 <fprintf@plt>
mov    $0x1,%edi
call   10d0 <exit@plt>
mov    -0x10(%rbp),%rdi
lea    0xdcd(%rip),%rsi
mov    $0x1,%edx
call   1040 <cwio_device_set_params@plt>
mov    -0x10(%rbp),%rdi
mov    $0x1,%esi
call   1090 <cwio_open@plt>
mov    -0x10(%rbp),%rdi
call   1050 <cwio_device_has_double_step@plt>
cmp    $0x0,%rax
je     1281 <main+0xc1>
mov    -0x20024(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x20024(%rbp)
mov    0x2d58(%rip),%rax
mov    (%rax),%edi
mov    -0x20024(%rbp),%edx
lea    0xd85(%rip),%rsi
mov    $0x0,%al
call   1070 <fprintf@plt>
mov    -0x18(%rbp),%rdi
mov    -0x20024(%rbp),%esi
lea    -0x20020(%rbp),%rax
xor    %edx,%edx
mov    $0x1,%r8d
mov    $0x190,%r9d
mov    %r8d,%ecx
mov    %rax,(%rsp)
movl   $0x20000,0x8(%rsp)
call   10b0 <cwio_data_set_params@plt>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   10c0 <cwio_read@plt>
mov    %eax,-0x20028(%rbp)
lea    -0x20020(%rbp),%rdi
mov    -0x20028(%rbp),%edx
mov    0x2ce0(%rip),%rax
mov    (%rax),%ecx
mov    $0x1,%esi
call   10e0 <fwrite@plt>
mov    -0x10(%rbp),%rdi
call   10a0 <cwio_close@plt>
xor    %eax,%eax
add    $0x20040,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x20008,%rsp
xor    %eax,%eax
call   1060 <cwio_device_struct_size@plt>
mov    %eax,%edi
call   1080 <alloca@plt>
mov    %rax,%rbx
xor    %eax,%eax
call   1030 <cwio_data_struct_size@plt>
mov    %eax,%edi
call   1080 <alloca@plt>
test   %rbx,%rbx
je     12b7 <main+0xf7>
mov    %rax,%r14
test   %rax,%rax
je     12b7 <main+0xf7>
lea    0xe07(%rip),%rsi
mov    %rbx,%rdi
mov    $0x1,%edx
call   1040 <cwio_device_set_params@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
call   1090 <cwio_open@plt>
mov    %rbx,%rdi
call   1050 <cwio_device_has_double_step@plt>
xor    %ecx,%ecx
test   %rax,%rax
sete   %cl
lea    (%rcx,%rcx,4),%ebp
add    $0x5,%ebp
mov    0x2da1(%rip),%rax
mov    (%rax),%edi
lea    0xdd4(%rip),%rsi
mov    %ebp,%edx
xor    %eax,%eax
call   1070 <fprintf@plt>
mov    %rsp,%r15
mov    %r14,%rdi
mov    %ebp,%esi
xor    %edx,%edx
mov    $0x1,%ecx
mov    $0x1,%r8d
mov    $0x190,%r9d
push   $0x20000
push   %r15
call   10b0 <cwio_data_set_params@plt>
add    $0x10,%rsp
mov    %rbx,%rdi
mov    %r14,%rsi
call   10c0 <cwio_read@plt>
mov    0x2d4a(%rip),%rcx
mov    (%rcx),%ecx
mov    %r15,%rdi
mov    $0x1,%esi
mov    %eax,%edx
call   10e0 <fwrite@plt>
mov    %rbx,%rdi
call   10a0 <cwio_close@plt>
xor    %eax,%eax
add    $0x20008,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret
mov    0x2d22(%rip),%rax
mov    (%rax),%edi
lea    0xd39(%rip),%rsi
xor    %eax,%eax
call   1070 <fprintf@plt>
mov    $0x1,%edi
call   10d0 <exit@plt>

LLVM IR (-O0):
%struct.cwio_device = type { i32 }
%struct.cwio_data = type { i32 }
@stderr = global i32 0
@.str = [15 x i8] c"out of memory\0A\00"
@.str.1 = [13 x i8] c"/dev/cw0raw0\00"
@.str.2 = [18 x i8] c"reading track %d\0A\00"
@stdout = global i32 0
define i32 @main() {
%1 = alloca i32
%2 = alloca %struct.cwio_device*
%3 = alloca %struct.cwio_data*
%4 = alloca [131072 x i8]
%5 = alloca i32
%6 = alloca i32
store i32 0, i32* %1
store i32 10, i32* %5
%7 = call i32 (...) @cwio_device_struct_size()
%8 = call i8* @alloca(i32 %7)
%9 = bitcast i8* %8 to %struct.cwio_device*
store %struct.cwio_device* %9, %struct.cwio_device** %2
%10 = call i32 (...) @cwio_data_struct_size()
%11 = call i8* @alloca(i32 %10)
%12 = bitcast i8* %11 to %struct.cwio_data*
store %struct.cwio_data* %12, %struct.cwio_data** %3
%13 = load %struct.cwio_device*, %struct.cwio_device** %2
%14 = icmp eq %struct.cwio_device* %13, null
br i1 %14, label %18, label %15
15: ; preds = %0
%16 = load %struct.cwio_data*, %struct.cwio_data** %3
%17 = icmp eq %struct.cwio_data* %16, null
br i1 %17, label %18, label %22
18: ; preds = %15, %0
%19 = load i32, i32* @stderr
%20 = call i32 (i32, i8*, ...) @fprintf(i32 %19, i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0))
%21 = call i32 @exit(i32 1)
unreachable
22: ; preds = %15
%23 = load %struct.cwio_device*, %struct.cwio_device** %2
%24 = call i32 @cwio_device_set_params(%struct.cwio_device* %23, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 1)
%25 = load %struct.cwio_device*, %struct.cwio_device** %2
%26 = call i32 @cwio_open(%struct.cwio_device* %25, i32 1)
%27 = load %struct.cwio_device*, %struct.cwio_device** %2
%28 = call i64 @cwio_device_has_double_step(%struct.cwio_device* %27)
%29 = icmp ne i64 %28, 0
br i1 %29, label %30, label %33
30: ; preds = %22
%31 = load i32, i32* %5
%32 = sdiv i32 %31, 2
store i32 %32, i32* %5
br label %33
33: ; preds = %30, %22
%34 = load i32, i32* @stderr
%35 = load i32, i32* %5
%36 = call i32 (i32, i8*, ...) @fprintf(i32 %34, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.2, i64 0, i64 0), i32 %35)
%37 = load %struct.cwio_data*, %struct.cwio_data** %3
%38 = load i32, i32* %5
%39 = getelementptr inbounds [131072 x i8], [131072 x i8]* %4, i64 0, i64 0
%40 = call i32 @cwio_data_set_params(%struct.cwio_data* %37, i32 %38, i32 0, i32 1, i32 1, i32 400, i8* %39, i32 131072)
%41 = load %struct.cwio_device*, %struct.cwio_device** %2
%42 = load %struct.cwio_data*, %struct.cwio_data** %3
%43 = call i32 @cwio_read(%struct.cwio_device* %41, %struct.cwio_data* %42)
store i32 %43, i32* %6
%44 = getelementptr inbounds [131072 x i8], [131072 x i8]* %4, i64 0, i64 0
%45 = load i32, i32* %6
%46 = load i32, i32* @stdout
%47 = call i32 @fwrite(i8* %44, i32 1, i32 %45, i32 %46)
%48 = load %struct.cwio_device*, %struct.cwio_device** %2
%49 = call i32 @cwio_close(%struct.cwio_device* %48)
ret i32 0
}

LLVM IR (-O2):
%struct.cwio_device = type { i32 }
%struct.cwio_data = type { i32 }
@stderr = global i32 0
@.str = [15 x i8] c"out of memory\0A\00"
@.str.1 = [13 x i8] c"/dev/cw0raw0\00"
@.str.2 = [18 x i8] c"reading track %d\0A\00"
@stdout = global i32 0
define i32 @main() {
%1 = alloca [131072 x i8]
%2 = getelementptr inbounds [131072 x i8], [131072 x i8]* %1, i64 0, i64 0
%3 = tail call i32 (...) @cwio_device_struct_size()
%4 = tail call i8* @alloca(i32 %3)
%5 = bitcast i8* %4 to %struct.cwio_device*
%6 = tail call i32 (...) @cwio_data_struct_size()
%7 = tail call i8* @alloca(i32 %6)
%8 = bitcast i8* %7 to %struct.cwio_data*
%9 = icmp eq i8* %4, null
%10 = icmp eq i8* %7, null
%11 = select i1 %9, i1 true, i1 %10
br i1 %11, label %12, label %16
12: ; preds = %0
%13 = load i32, i32* @stderr
%14 = tail call i32 (i32, i8*, ...) @fprintf(i32 %13, i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0))
%15 = tail call i32 @exit(i32 1)
unreachable
16: ; preds = %0
%17 = tail call i32 @cwio_device_set_params(%struct.cwio_device* %5, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0), i32 1)
%18 = tail call i32 @cwio_open(%struct.cwio_device* %5, i32 1)
%19 = tail call i64 @cwio_device_has_double_step(%struct.cwio_device* %5)
%20 = icmp eq i64 %19, 0
%21 = select i1 %20, i32 10, i32 5
%22 = load i32, i32* @stderr
%23 = tail call i32 (i32, i8*, ...) @fprintf(i32 %22, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.2, i64 0, i64 0), i32 %21)
%24 = call i32 @cwio_data_set_params(%struct.cwio_data* %8, i32 %21, i32 0, i32 1, i32 1, i32 400, i8* %2, i32 131072)
%25 = call i32 @cwio_read(%struct.cwio_device* %5, %struct.cwio_data* %8)
%26 = load i32, i32* @stdout
%27 = call i32 @fwrite(i8* %2, i32 1, i32 %25, i32 %26)
%28 = call i32 @cwio_close(%struct.cwio_device* %5)
ret i32 0
}