// File: /workspace/github_c_makefile_star2_O3/aquaxis[P]synverll/src/parser_ir_memory.c
// Function: parser_memory_tree
int parser_memory_tree()
{
	MEMORY_TREE		*memory_tree_current;
	PARSER_TREE_IR	*now_parser_tree_ir;
	char *line;
	char token[STR_MAX];
	char type[STR_MAX];
	char verilog_args[STR_MAX];
	char verilog_proc[STR_MAX];
	char verilog_decl[STR_MAX];
	char *str;
	int num = 0;
	int width;

    printf(" -> Parser Memory Tree\n");

	strcpy(verilog_args, "");

    now_parser_tree_ir = parser_tree_ir_top;
    while(now_parser_tree_ir != NULL){

		if( now_parser_tree_ir->stage == 0 ){
			// stage = 0のみ対象
			switch(now_parser_tree_ir->flag){
				case PARSER_IR_FLAG_ARRAY:
						memory_tree_current = alloc_memory_tree();
						
						memory_tree_current->label	= charalloc(now_parser_tree_ir->label);
						memory_tree_current->type	= charalloc(now_parser_tree_ir->array.type);
						memory_tree_current->num	= -1;
						memory_tree_current->flag	= MEMORY_FLAG_GLOBAL;
						str = charalloc(memory_tree_current->label);
						sprintf(verilog_args, "\tinput [31:0] __base_%s,", convname(sep_p(str)));
						sprintf(verilog_proc, "\t\t\t__sig_%s <= __base_%s;", convname(sep_p(str)), convname(sep_p(str)));
						sprintf(verilog_decl, "\treg [31:0] __sig_%s;", convname(sep_p(str)));
						free(str);
						memory_tree_current->verilog_args = charalloc(verilog_args);
						memory_tree_current->verilog_proc = charalloc(verilog_proc);
						memory_tree_current->verilog_decl = charalloc(verilog_decl);
					break;
				default:
					// ARRAY以外は処理の対象外
					break;
			}
		}else{
			switch(now_parser_tree_ir->flag){
				case PARSER_IR_FLAG_MODULE:
					/*
					 * 関数の引数で受け渡されているポインタのメモリタイプを抜き出す
					 */
					/*
					 * ToDo:
					 *  ここでモジュールの引数の番号の関連付けを作成しなければいけない
					 *  ここで信号定義が作成できるはず
					 */
					line = charalloc(now_parser_tree_ir->module.argument);

					// "("
					get_token_llvm(line, token);

					while(strlen(line) > 0){
						// タイプ
						get_irtype_llvm(line, token);
						if(!strcmp(token, "") || !strcmp(token, ")")) break;
						strcpy(type, token);
						if(is_pointer_type(token)){
							// ポインタの場合
							memory_tree_current = alloc_memory_tree();
							memory_tree_current->flag = MEMORY_FLAG_REGISTER;
							memory_tree_current->num = num++;

							do{
								get_token_llvm(line, token);
								if(!strcmp(token, "align")){
									get_token_llvm(line, token);
									get_token_llvm(line, token);
								}
							}while(
								!strcmp(token, "zeroext") ||
								!strcmp(token, "signext") ||
								!strcmp(token, "inreg") ||
								!strcmp(token, "byval") ||
								!strcmp(token, "sret") ||
								!strcmp(token, "align") ||
								!strcmp(token, "noalias") ||
								!strcmp(token, "nocapture") ||
								!strcmp(token, "nest") ||
								!strcmp(token, "readonly") ||
								!strcmp(token, "readnone") ||
								!strcmp(token, "returned") ||
								!strcmp(token, "dereferenceable") ||
								!strcmp(token, "dereferenceable_or_null")
							);

							memory_tree_current->label = charalloc(token);
							{
								width = get_width(type);
									str = charalloc(memory_tree_current->label);
									sprintf(verilog_args, "\tinput [%d:0] __args_%s,", (width-1), convname(sep_p(str)));
									sprintf(verilog_proc, "\t\t\t__sig_%s <= __args_%s;", convname(sep_p(str)), convname(sep_p(str)));
									sprintf(verilog_decl, "\treg [%d:0] __sig_%s;", (width-1), convname(sep_p(str)));
									free(str);
								convtype(type);
								memory_tree_current->type = charalloc(type);
								memory_tree_current->size = width/4;
							}
						}else{
							/*
							 * 変数の場合は処理をしません。
							 * タイプで入力サイズを変えなければいけないかもしれない。
							 */
							memory_tree_current = alloc_memory_tree();
							memory_tree_current->num = num++;
							memory_tree_current->flag = MEMORY_FLAG_REGISTER;

							get_irtype_llvm(line, token);
							/*
							 * zeroext
							 * signext
							 * inreg
							 * byval
							 * inalloca
							 * sret
							 * align <h>
							 * noalias
							 * nocapture
							 * nest
							 * returned
							 * nonull
							 * dereferenceable(<n>)
							 * dereferenceable_or_null(<n>)
							 */
							if(!strcmp(token, "zeroext") || !strcmp(token, "signext")){
								get_token_llvm(line, token);
							}

							memory_tree_current->label = charalloc(token);

							width = get_width(type);

							sprintf(verilog_args, "\tinput [%d:0] __args_%s,", (width-1), convname(sep_p(token)));
							sprintf(verilog_proc, "\t\t\t__sig_%s <= __args_%s;", convname(sep_p(token)), convname(sep_p(token)));
							sprintf(verilog_decl, "\treg [%d:0] __sig_%s;", (width-1), convname(sep_p(token)));

							memory_tree_current->type = charalloc(type);
							memory_tree_current->size = width/8;
						}
						memory_tree_current->verilog_args = charalloc(verilog_args);
						memory_tree_current->verilog_proc = charalloc(verilog_proc);
						memory_tree_current->verilog_decl = charalloc(verilog_decl);
						// 次の","か")"まで読み飛ばし
						do{
							get_token_llvm(line, token);
						}while(strcmp(token, ",") && strcmp(token, ")"));
					}

					free(line);

					break;

				case PARSER_IR_FLAG_ALLOCA:
					/*
					 * allocaされているメモリを登録する
					 */
					memory_tree_current = alloc_memory_tree();
					memory_tree_current->label = charalloc(now_parser_tree_ir->label);
					memory_tree_current->type = charalloc(now_parser_tree_ir->alloca.type);
					memory_tree_current->flag = MEMORY_FLAG_LOCAL;

					break;

				case PARSER_IR_FLAG_RETURN:
					memory_tree_current = alloc_memory_tree();
					memory_tree_current->flag = MEMORY_FLAG_RETURN;

					if(strcmp(now_parser_tree_ir->ret.type, "void")){
						width = get_width(now_parser_tree_ir->ret.type);
						memory_tree_current->label = charalloc(now_parser_tree_ir->ret.name);
						memory_tree_current->type = charalloc(now_parser_tree_ir->ret.type);
						memory_tree_current->size = width/8;

						sprintf(verilog_args, "\toutput reg [%d:0] __func_result\n", (width-1));
					}else{
						memory_tree_current->label = charalloc("");
						memory_tree_current->type = charalloc("void");
						memory_tree_current->size = 0;

						sprintf(verilog_args, "\toutput reg __func_result\n");
					}

					memory_tree_current->verilog_args = charalloc(verilog_args);

					break;
				default:
					// 他は何もしない
					break;
			}
		}
        now_parser_tree_ir = now_parser_tree_ir->next_ptr;
    }
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1448, %rsp           # imm = 0x1448
leaq 0x8d99(%rip), %rdi      # 0xe9bd
callq 0x1070
movb $0x0, 0x440(%rsp)
leaq 0xe4f8(%rip), %rax      # 0x14130
movq (%rax), %rbx
testq %rbx, %rbx
je 0x649c
leaq 0x40(%rsp), %r15
movabsq $0x7478656f72657a, %r12 # imm = 0x7478656F72657A
movabsq $0x7478656e676973, %r13 # imm = 0x7478656E676973
movl $0x67696c61, %r14d      # imm = 0x67696C61
movl $0x65726e69, %ebp       # imm = 0x65726E69
movl $0x0, 0x24(%rsp)
cmpl $0x0, 0x1c(%rbx)
movl 0x10(%rbx), %eax
je 0x61e2
cmpl $0x9, %eax
je 0x63dc
cmpl $0x12, %eax
je 0x633b
cmpl $0xf, %eax
jne 0x648f
movq %rbx, 0x18(%rsp)
leaq 0x1430(%rbx), %rdi
callq 0x137c
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
callq 0xcaa7
cmpb $0x0, (%rbx)
je 0x6419
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1fbb
cmpb $0x0, 0x40(%rsp)
je 0x6419
cmpw $0x29, 0x40(%rsp)
je 0x6419
leaq 0x840(%rsp), %rdi
movq %r15, %rsi
callq 0x1060
movq %r15, %rdi
callq 0x3e5b
movl %eax, 0x10(%rsp)
callq 0x57cc
movq %rax, %rcx
cmpl $0x0, 0x10(%rsp)
movq %rax, 0x8(%rsp)
je 0x601f
movl $0x4, 0x10(%rcx)
movl 0x24(%rsp), %eax
movl %eax, 0x40(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcaa7
movl 0x40(%rsp), %eax
xorl %r14d, %eax
movzwl 0x44(%rsp), %ecx
xorl $0x6e, %ecx
orl %eax, %ecx
jne 0x5d58
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcaa7
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcaa7
movq 0x40(%rsp), %rax
cmpq %r13, %rax
je 0x5d24
cmpq %r12, %rax
je 0x5d24
movl 0x40(%rsp), %ecx
xorl %ebp, %ecx
movzwl 0x44(%rsp), %edx
xorl $0x67, %edx
orl %ecx, %edx
je 0x5d24
movl 0x40(%rsp), %ecx
movl $0x61767962, %edx       # imm = 0x61767962
xorl %edx, %ecx
movzwl 0x44(%rsp), %edx
xorl $0x6c, %edx
orl %ecx, %edx
je 0x5d24
movl 0x40(%rsp), %ecx
movl $0x74657273, %edx       # imm = 0x74657273
xorl %edx, %ecx
movzbl 0x44(%rsp), %edx
orl %ecx, %edx
je 0x5d24
movl 0x40(%rsp), %edx
xorl %r14d, %edx
movzwl 0x44(%rsp), %esi
xorl $0x6e, %esi
xorl %ecx, %ecx
orl %edx, %esi
setne %dl
movabsq $0x7361696c616f6e, %rsi # imm = 0x7361696C616F6E
cmpq %rsi, %rax
je 0x5d24
movb %dl, %cl
testl %ecx, %ecx
je 0x5d24
movq 0x40(%rsp), %rax
movabsq $0x7275747061636f6e, %rcx # imm = 0x7275747061636F6E
xorq %rcx, %rax
movzwl 0x48(%rsp), %ecx
xorq $0x65, %rcx
orq %rax, %rcx
je 0x5d24
movl 0x40(%rsp), %eax
movl $0x7473656e, %ecx       # imm = 0x7473656E
xorl %ecx, %eax
movzbl 0x44(%rsp), %ecx
orl %eax, %ecx
je 0x5d24
movq 0x40(%rsp), %rax
movabsq $0x796c6e6f64616572, %rcx # imm = 0x796C6E6F64616572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5d24
movq 0x40(%rsp), %rax
movabsq $0x656e6f6e64616572, %rcx # imm = 0x656E6F6E64616572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5d24
movq 0x40(%rsp), %rax
movabsq $0x64656e7275746572, %rcx # imm = 0x64656E7275746572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5d24
movdqa 0x40(%rsp), %xmm0
pcmpeqb 0x88df(%rip), %xmm0     # 0xe760
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x5d24
movq 0x50(%rsp), %xmm0
pcmpeqb 0x88d2(%rip), %xmm0     # 0xe770
movdqa 0x40(%rsp), %xmm1
pcmpeqb 0x88d4(%rip), %xmm1     # 0xe780
pand %xmm0, %xmm1
pmovmskb %xmm1, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x5d24
movq %r15, %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x840(%rsp), %rdi
callq 0x12dc
movq %rax, 0x30(%rsp)
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0x137c
movq %rax, %rcx
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x5f03
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5f07
leaq 0x1(%rcx), %rdi
movq 0x30(%rsp), %rax
decl %eax
movl %eax, 0x28(%rsp)
movq %rcx, 0x10(%rsp)
callq 0x139f
leaq 0x440(%rsp), %rdi
leaq 0x8948(%rip), %rsi      # 0xe873
movl 0x28(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x10(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x5f4e
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5f52
leaq 0x1(%rcx), %rdi
callq 0x139f
movq 0x10(%rsp), %rcx
movq %rax, 0x38(%rsp)
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x5f71
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5f75
leaq 0x1(%rcx), %rdi
callq 0x139f
leaq 0x1040(%rsp), %rdi
leaq 0x8903(%rip), %rsi      # 0xe88c
movq 0x38(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x10(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x5fad
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5fb3
movq %rcx, %rdi
incq %rdi
callq 0x139f
leaq 0xc40(%rsp), %rdi
leaq 0x88df(%rip), %rsi      # 0xe8a6
movl 0x28(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x10(%rsp), %rdi
callq 0x1030
leaq 0x840(%rsp), %rdi
callq 0x1419
leaq 0x840(%rsp), %rdi
callq 0x137c
movq 0x8(%rsp), %rdx
movq %rax, 0x20(%rdx)
movq 0x30(%rsp), %rcx
leal 0x3(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
sarl $0x2, %eax
leaq 0x440(%rsp), %rdi
jmp 0x617e
movl 0x24(%rsp), %eax
movl %eax, 0x40(%rcx)
movl $0x4, 0x10(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1fbb
movq 0x40(%rsp), %rax
cmpq %r12, %rax
je 0x6047
cmpq %r13, %rax
jne 0x6052
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcaa7
movq %r15, %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x840(%rsp), %rdi
callq 0x12dc
movq %rax, 0x30(%rsp)
movb 0x40(%rsp), %dl
cmpb $0x40, %dl
movq %r15, %rdi
leaq 0x41(%rsp), %rcx
cmoveq %rcx, %rdi
decl %eax
movl %eax, 0x10(%rsp)
cmpb $0x25, %dl
cmoveq %rcx, %rdi
callq 0x139f
leaq 0x440(%rsp), %rdi
leaq 0x87ca(%rip), %rsi      # 0xe873
movl 0x10(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
leaq 0x41(%rsp), %rcx
cmoveq %rcx, %rdi
cmpb $0x25, %al
cmoveq %rcx, %rdi
callq 0x139f
movb 0x40(%rsp), %cl
cmpb $0x40, %cl
movq %r15, %rdi
leaq 0x41(%rsp), %rdx
cmoveq %rdx, %rdi
movq %rax, 0x28(%rsp)
cmpb $0x25, %cl
cmoveq %rdx, %rdi
callq 0x139f
leaq 0x1040(%rsp), %rdi
leaq 0x8785(%rip), %rsi      # 0xe88c
movq 0x28(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
leaq 0x41(%rsp), %rcx
cmoveq %rcx, %rdi
cmpb $0x25, %al
cmoveq %rcx, %rdi
callq 0x139f
leaq 0xc40(%rsp), %rdi
leaq 0x8764(%rip), %rsi      # 0xe8a6
movl 0x10(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
leaq 0x840(%rsp), %rdi
callq 0x137c
leaq 0x440(%rsp), %rdi
movq 0x8(%rsp), %rdx
movq %rax, 0x20(%rdx)
movq 0x30(%rsp), %rcx
leal 0x7(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
sarl $0x3, %eax
movl %eax, 0x44(%rdx)
incl 0x24(%rsp)
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x28(%rcx)
leaq 0x1040(%rsp), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x30(%rcx)
leaq 0xc40(%rsp), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x38(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcaa7
movzwl 0x40(%rsp), %eax
cmpl $0x2c, %eax
je 0x5cb7
cmpl $0x29, %eax
jne 0x61bf
jmp 0x5cb7
cmpl $0x6, %eax
jne 0x648f
callq 0x57cc
movq %rax, 0x8(%rsp)
leaq 0x30(%rbx), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
movq %rbx, 0x18(%rsp)
leaq 0x3c34(%rbx), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x20(%rcx)
movl $0xffffffff, 0x40(%rcx) # imm = 0xFFFFFFFF
movl $0x1, 0x10(%rcx)
movq 0x18(%rcx), %rdi
callq 0x137c
movq %rax, %rbx
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x624b
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x624f
leaq 0x1(%rbx), %rdi
callq 0x139f
leaq 0x440(%rsp), %rdi
leaq 0x855e(%rip), %rsi      # 0xe7c1
movq %rax, %rdx
xorl %eax, %eax
callq 0x11a0
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x627d
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x6281
leaq 0x1(%rbx), %rdi
callq 0x139f
movq %rax, 0x10(%rsp)
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x629b
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x629f
leaq 0x1(%rbx), %rdi
callq 0x139f
leaq 0x1040(%rsp), %rdi
leaq 0x8527(%rip), %rsi      # 0xe7da
movq 0x10(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x62d2
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x62d8
movq %rbx, %rdi
incq %rdi
callq 0x139f
leaq 0xc40(%rsp), %rdi
leaq 0x8508(%rip), %rsi      # 0xe7f4
movq %rax, %rdx
xorl %eax, %eax
callq 0x11a0
movq %rbx, %rdi
callq 0x1030
leaq 0x440(%rsp), %rdi
callq 0x137c
movq 0x8(%rsp), %rbx
movq %rax, 0x28(%rbx)
leaq 0x1040(%rsp), %rdi
callq 0x137c
movq %rax, 0x30(%rbx)
leaq 0xc40(%rsp), %rdi
callq 0x137c
movq %rax, 0x38(%rbx)
jmp 0x6421
callq 0x57cc
movq %rax, 0x8(%rsp)
movl $0x5, 0x10(%rax)
leaq 0x6434(%rbx), %rdi
movq %rdi, 0x10(%rsp)
leaq 0x7ca5(%rip), %rsi      # 0xe004
callq 0x1100
testl %eax, %eax
je 0x6428
movq 0x10(%rsp), %rdi
callq 0x12dc
movq %rbx, 0x18(%rsp)
movl %eax, %ebx
movq 0x18(%rsp), %rax
leaq 0x6834(%rax), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
movq 0x10(%rsp), %rdi
callq 0x137c
leal 0x7(%rbx), %ecx
testl %ebx, %ebx
cmovnsl %ebx, %ecx
movq 0x8(%rsp), %rdx
movq %rax, 0x20(%rdx)
sarl $0x3, %ecx
movl %ecx, 0x44(%rdx)
decl %ebx
leaq 0x440(%rsp), %rdi
leaq 0x84f3(%rip), %rsi      # 0xe8bc
movl %ebx, %edx
movq 0x18(%rsp), %rbx
xorl %eax, %eax
callq 0x11a0
jmp 0x6479
callq 0x57cc
movq %rbx, 0x18(%rsp)
movq %rax, %rbx
movq 0x18(%rsp), %rax
leaq 0x30(%rax), %rdi
callq 0x137c
movq %rax, 0x18(%rbx)
movq 0x18(%rsp), %rax
leaq 0x6c34(%rax), %rdi
callq 0x137c
movq %rax, 0x20(%rbx)
movl $0x2, 0x10(%rbx)
jmp 0x6421
movq %rbx, %rdi
callq 0x1030
movq 0x18(%rsp), %rbx
jmp 0x648f
leaq 0x9b94(%rip), %rdi      # 0xffc3
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x7bc0(%rip), %rdi      # 0xe004
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x20(%rcx)
movl $0x0, 0x44(%rcx)
movups 0x847e(%rip), %xmm0     # 0xe8de
movaps %xmm0, 0x440(%rsp)
movdqu 0x8479(%rip), %xmm0     # 0xe8e9
movdqu %xmm0, 0x44b(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x137c
movq 0x8(%rsp), %rcx
movq %rax, 0x28(%rcx)
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
jne 0x5c70
xorl %eax, %eax
addq $0x1448, %rsp           # imm = 0x1448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq