// File: /workspace/github_cpp_makefile_star2_O3/CobaltXII[P]cxcc/cxcc.cpp
// Function: main
int main(int argc, char** argv) {
	if (argc != 2 && argc != 3 && argc != 4) {
		usage(argv[0]);
	} else if (argc == 4) {
		if (std::string(argv[3]) != "-o") {
			usage(argv[0]);
		}
	}

	// Open the file.
	std::ifstream file_stream(argv[1]);
	if (!file_stream.is_open()) {
		std::cerr << "Could not open file \"" << argv[1] << "\"." << std::endl;
		exit(1);
	}

	// Load the file.
	std::string file_content(
		(std::istreambuf_iterator<char>(file_stream)),
		(std::istreambuf_iterator<char>())
	);
	file_stream.close();

	// Parse the second argument.
	std::string outfile;
	if (argc == 3) {
		outfile = argv[2];
	} else if (argc == 4) {
		outfile = "tmp" + std::to_string(time(NULL)) + ".s";
	} else {
		outfile = std::string(argv[1]) + ".s";
	}

	// Open the output file.
	std::FILE* output_file = fopen(outfile.c_str(), "w");

	// Parse the file (implicity lexes the file).
	program_t program = parser_t(argv[1], file_content).parse();

	// Validate the program.
	semantic_analyzer_t semantic_analyzer(argv[1], file_content);
	semantic_analyzer.validate(program);

	// Compile the program.
	compiler_t compiler(program, output_file);
	compiler.compile();
	fclose(output_file);

	// Optionally assembly the output using gcc.
	if (argc == 4) {
		// Assemble the output.
		std::stringstream gcc_cmd;
		gcc_cmd << "gcc " << outfile << " -o " << argv[2];
		system(gcc_cmd.str().c_str());
		// Remove the temporary file.
		std::stringstream rm_cmd;
		rm_cmd << "rm -f " << outfile;
		system(rm_cmd.str().c_str());
	}

	// Exit successfully.
	exit(EXIT_SUCCESS);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x698, %rsp            # imm = 0x698
movq %rsi, %rbx
movl %edi, %r14d
leal -0x5(%r14), %eax
cmpl $-0x4, %eax
ja 0x51f8
movq (%rbx), %rdi
callq 0x5114
cmpl $0x4, %r14d
jne 0x524f
movq 0x18(%rbx), %rsi
leaq 0x490(%rsp), %r15
leaq 0x308(%rsp), %rdx
movq %r15, %rdi
callq 0x5bc2
leaq 0x14665(%rip), %rsi     # 0x19886
movq %r15, %rdi
callq 0x30b0
movl %eax, %ebp
movq (%r15), %rdi
leaq 0x4a0(%rsp), %rax
cmpq %rax, %rdi
je 0x524b
movq 0x4a0(%rsp), %rsi
incq %rsi
callq 0x3280
testl %ebp, %ebp
jne 0x51f0
movq 0x8(%rbx), %rsi
leaq 0x490(%rsp), %rdi
movl $0x8, %edx
callq 0x33d0
leaq 0x508(%rsp), %rdi
callq 0x3080
testb %al, %al
je 0x530a
movq 0x490(%rsp), %rax
movq -0x18(%rax), %rax
movq 0x578(%rsp,%rax), %rsi
leaq 0x38(%rsp), %rbp
movq %rbp, -0x10(%rbp)
leaq 0x28(%rsp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
callq 0x17cd4
leaq 0x490(%rsp), %rdi
callq 0x3070
leaq 0x18(%rsp), %r13
movq %r13, -0x10(%r13)
movq $0x0, -0x8(%r13)
movb $0x0, (%r13)
cmpl $0x4, %r14d
je 0x53b2
cmpl $0x3, %r14d
jne 0x542d
movq 0x10(%rbx), %r15
movq %r15, %rdi
callq 0x3110
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
movq %r15, %rcx
movq %rax, %r8
callq 0x3340
jmp 0x5648
movq 0x1acdf(%rip), %r14     # 0x1fff0
leaq 0x14571(%rip), %rsi     # 0x19889
movl $0x15, %edx
movq %r14, %rdi
callq 0x32b0
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
jne 0x5348
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x33a0
jmp 0x5362
movq %rbx, %rdi
callq 0x3110
movq 0x1ac99(%rip), %rdi     # 0x1fff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32b0
movq 0x1ac87(%rip), %rbx     # 0x1fff0
leaq 0x1452f(%rip), %rsi     # 0x1989f
movl $0x2, %edx
movq %rbx, %rdi
callq 0x32b0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x3240
movsbl %al, %esi
movq 0x1ac55(%rip), %rdi     # 0x1fff0
callq 0x3030
movq %rax, %rdi
callq 0x3180
movl $0x1, %edi
callq 0x32e0
xorl %edi, %edi
callq 0x3220
movq %rax, %r12
movq %rax, %r15
negq %r15
cmovsq %rax, %r15
movl $0x1, %r13d
cmpq $0xa, %r15
jb 0x5490
movl $0x4, %r13d
movabsq $0x346dc5d63886594b, %rsi # imm = 0x346DC5D63886594B
movq %r15, %rcx
cmpq $0x63, %rcx
jbe 0x5487
cmpq $0x3e7, %rcx            # imm = 0x3E7
jbe 0x548d
cmpq $0x2710, %rcx           # imm = 0x2710
jb 0x5490
movq %rcx, %rax
mulq %rsi
shrq $0xb, %rdx
addl $0x4, %r13d
cmpq $0x1869f, %rcx          # imm = 0x1869F
movq %rdx, %rcx
ja 0x53e9
addl $-0x3, %r13d
jmp 0x5490
movq 0x8(%rbx), %rsi
leaq 0x180(%rsp), %rdi
leaq 0x88(%rsp), %rdx
callq 0x5bc2
leaq 0x14459(%rip), %rsi     # 0x198a6
leaq 0x180(%rsp), %rdi
callq 0x33f0
leaq 0x318(%rsp), %r12
movq %r12, -0x10(%r12)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0x5532
movups (%rcx), %xmm0
movups %xmm0, (%r12)
jmp 0x5545
addl $-0x2, %r13d
jmp 0x5490
decl %r13d
shrq $0x3f, %r12
leal (%r12,%r13), %esi
leaq 0x98(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x88(%rsp), %rdi
movl $0x2d, %edx
callq 0x32c0
leaq 0x88(%rsp), %rbp
addq (%rbp), %r12
movq %r12, %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x7198
leaq 0x143cb(%rip), %rsi     # 0x198a2
leaq 0x180(%rsp), %rdi
movq %rbp, %rdx
callq 0x5cb8
leaq 0x143b8(%rip), %rsi     # 0x198a6
leaq 0x180(%rsp), %rdi
callq 0x33f0
leaq 0x318(%rsp), %r12
movq %r12, -0x10(%r12)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
leaq 0x38(%rsp), %rbp
leaq 0x18(%rsp), %r13
jne 0x55ab
movups (%rcx), %xmm0
movups %xmm0, (%r12)
jmp 0x55be
movq %rdx, 0x308(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x318(%rsp)
movq 0x8(%rax), %rdx
leaq 0x308(%rsp), %r15
movq %rdx, 0x8(%r15)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x32f0
movq (%r15), %rdi
cmpq %r12, %rdi
je 0x5589
movq 0x318(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5648
movq 0x190(%rsp), %rsi
jmp 0x5640
movq %rdx, 0x308(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x318(%rsp)
movq 0x8(%rax), %rdx
leaq 0x308(%rsp), %r15
movq %rdx, 0x8(%r15)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x32f0
movq (%r15), %rdi
cmpq %r12, %rdi
je 0x5602
movq 0x318(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5623
movq 0x190(%rsp), %rsi
incq %rsi
callq 0x3280
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x5648
movq 0x98(%rsp), %rsi
incq %rsi
callq 0x3280
movq 0x8(%rsp), %rdi
leaq 0x14255(%rip), %rsi     # 0x198a9
callq 0x32d0
movq %rax, %r15
movq 0x8(%rbx), %rsi
leaq 0x108(%rsp), %rdi
leaq 0x180(%rsp), %rdx
callq 0x5bc2
leaq 0x78(%rsp), %r12
movq %r12, -0x10(%r12)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
leaq 0x68(%rsp), %rdi
callq 0x179ce
leaq 0x308(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x5d28
leaq 0x140(%rsp), %rdi
leaq 0x308(%rsp), %rsi
callq 0x6252
leaq 0x308(%rsp), %rdi
callq 0x646e
movq 0x68(%rsp), %rdi
cmpq %r12, %rdi
je 0x56e9
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x118(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x570a
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x3280
movq 0x8(%rbx), %rsi
leaq 0xe8(%rsp), %rdi
leaq 0x308(%rsp), %rdx
callq 0x5bc2
leaq 0x58(%rsp), %r12
movq %r12, -0x10(%r12)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
leaq 0x48(%rsp), %rdi
callq 0x179ce
leaq 0x88(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x64fe
movq 0x48(%rsp), %rdi
cmpq %r12, %rdi
je 0x5775
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0xf8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5796
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x88(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x6576
leaq 0x128(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x6ca8
leaq 0x158(%rsp), %rdi
leaq 0x128(%rsp), %rsi
movq %r15, %rdx
callq 0x6d40
leaq 0x128(%rsp), %rdi
callq 0x6d7e
leaq 0x158(%rsp), %rdi
callq 0x6dae
movq %r15, %rdi
callq 0x3260
cmpl $0x4, %r14d
jne 0x5962
leaq 0x308(%rsp), %r14
movq %r14, %rdi
callq 0x3190
leaq 0x318(%rsp), %r15
leaq 0x14088(%rip), %rsi     # 0x198ab
movl $0x4, %edx
movq %r15, %rdi
callq 0x32b0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x32b0
movq %rax, %r15
leaq 0x14064(%rip), %rsi     # 0x198b0
movl $0x4, %edx
movq %rax, %rdi
callq 0x32b0
movq 0x10(%rbx), %rsi
movq %r15, %rdi
callq 0x3250
leaq 0x320(%rsp), %rsi
leaq 0x180(%rsp), %rdi
callq 0x3360
movq 0x180(%rsp), %rdi
callq 0x31e0
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x58a8
movq 0x190(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x180(%rsp), %rbx
movq %rbx, %rdi
callq 0x3190
leaq 0x190(%rsp), %r15
leaq 0x13fee(%rip), %rsi     # 0x198b5
movl $0x6, %edx
movq %r15, %rdi
callq 0x32b0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x32b0
leaq 0x198(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x3360
movq 0xc8(%rsp), %rdi
callq 0x31e0
leaq 0xd8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5929
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x3280
movq 0x1a690(%rip), %r15     # 0x1ffc0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x31b0
movl $0x80, %r12d
addq %r12, %rbx
movq %rbx, %rdi
callq 0x30e0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31b0
addq %r12, %r14
movq %r14, %rdi
callq 0x30e0
xorl %edi, %edi
callq 0x32e0
movq %rax, %rbx
leaq 0xd8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5994
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5994
jmp 0x5991
movq %rax, %rbx
movq 0x1a625(%rip), %rsi     # 0x1ffc0
leaq 0x180(%rsp), %rdi
callq 0x31b0
leaq 0x200(%rsp), %rdi
callq 0x30e0
jmp 0x59e4
jmp 0x59e1
movq %rax, %rbx
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x59e4
movq 0x190(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x59e4
jmp 0x59e1
movq %rax, %rbx
movq 0x1a5d5(%rip), %rsi     # 0x1ffc0
leaq 0x308(%rsp), %rdi
callq 0x31b0
leaq 0x388(%rsp), %rdi
callq 0x30e0
jmp 0x5a0c
jmp 0x5a09
movq %rax, %rbx
leaq 0x160(%rsp), %rdi
jmp 0x5a21
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x6d7e
jmp 0x5a2d
jmp 0x5a2a
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x7162
jmp 0x5a81
movq %rax, %rbx
movq 0x48(%rsp), %rdi
cmpq %r12, %rdi
je 0x5a5b
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5a5b
movq %rax, %rbx
leaq 0xf8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5a81
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5a81
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0x6d7e
jmp 0x5b72
movq %rax, %rbx
leaq 0x308(%rsp), %rdi
callq 0x646e
jmp 0x5aa8
movq %rax, %rbx
movq 0x68(%rsp), %rdi
cmpq %r12, %rdi
je 0x5af4
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5af4
movq %rax, %rbx
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
leaq 0x38(%rsp), %rbp
leaq 0x18(%rsp), %r13
je 0x5b3a
movq 0x190(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5b3a
movq %rax, %rbx
leaq 0x118(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5b72
movq 0x118(%rsp), %rsi
jmp 0x5b57
movq %rax, %rbx
leaq 0x190(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5b72
movq 0x190(%rsp), %rsi
jmp 0x5b57
movq %rax, %rbx
leaq 0x38(%rsp), %rbp
leaq 0x18(%rsp), %r13
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x5b72
movq 0x98(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5b72
jmp 0x5b6f
jmp 0x5b6f
movq %rax, %rbx
leaq 0x18(%rsp), %r13
jmp 0x5b72
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %r13, %rdi
je 0x5b8e
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5b8e
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %rbp, %rdi
je 0x5bac
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3280
jmp 0x5bac
jmp 0x5ba9
movq %rax, %rbx
leaq 0x490(%rsp), %rdi
callq 0x3090
movq %rbx, %rdi
callq 0x33b0
nop