// File: /workspace/github_c_makefile_star2_O2/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 0x7fe5(%rip), %rdi      # 0xd99d
callq 0x1070
leaq 0x440(%rsp), %rax
movb $0x0, (%rax)
leaq 0xd761(%rip), %r13      # 0x13130
leaq 0x762e(%rip), %rcx      # 0xd004
leaq 0x40(%rsp), %r15
movabsq $0x7478656e676973, %rbp # imm = 0x7478656E676973
leaq 0x7dfe(%rip), %r14      # 0xd7ea
pushq $0x6
popq %r12
movl $0x0, 0x1c(%rsp)
movq (%r13), %r13
testq %r13, %r13
je 0x61d7
cmpl $0x0, 0x1c(%r13)
movl 0x10(%r13), %eax
je 0x5f31
cmpl $0x9, %eax
je 0x6122
cmpl $0x12, %eax
je 0x6089
cmpl $0xf, %eax
jne 0x61ce
movq %r13, 0x28(%rsp)
leaq 0x1430(%r13), %rdi
callq 0x1372
movq %rax, %r13
movq %rax, %rdi
movq %r15, %rsi
callq 0xc4ad
cmpb $0x0, (%r13)
je 0x615e
movq %r13, %rdi
movq %r15, %rsi
callq 0x1ec1
cmpb $0x0, 0x40(%rsp)
je 0x615e
cmpw $0x29, 0x40(%rsp)
je 0x615e
leaq 0x1040(%rsp), %rdi
movq %r15, %rsi
callq 0x1060
movq %r15, %rdi
callq 0x3d39
movl %eax, 0x8(%rsp)
callq 0x5574
movq %rax, %rbx
cmpl $0x0, 0x8(%rsp)
movq %rax, 0x10(%rsp)
je 0x5d88
movl $0x4, 0x10(%rbx)
movl 0x1c(%rsp), %eax
movl %eax, 0x40(%rbx)
movq %r13, %rdi
movq %r15, %rsi
callq 0xc4ad
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x1140
testl %eax, %eax
jne 0x5af0
movq %r13, %rdi
movq %r15, %rsi
callq 0xc4ad
movq %r13, %rdi
movq %r15, %rsi
callq 0xc4ad
movq 0x40(%rsp), %rbx
cmpq %rbp, %rbx
je 0x5abd
movabsq $0x7478656f72657a, %rax # imm = 0x7478656F72657A
cmpq %rax, %rbx
je 0x5abd
movq %r15, %rdi
leaq 0x7cdd(%rip), %rsi      # 0xd7f0
movq %r12, %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7ccd(%rip), %rsi      # 0xd7f6
movq %r12, %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7cbd(%rip), %rsi      # 0xd7fc
pushq $0x5
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x1140
movabsq $0x7361696c616f6e, %rcx # imm = 0x7361696C616F6E
cmpq %rcx, %rbx
je 0x5abd
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7c7f(%rip), %rsi      # 0xd801
pushq $0xa
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7c6f(%rip), %rsi      # 0xd80b
pushq $0x5
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7c5a(%rip), %rsi      # 0xd810
pushq $0x9
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7c49(%rip), %rsi      # 0xd819
pushq $0x9
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
leaq 0x7c38(%rip), %rsi      # 0xd822
pushq $0x9
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movdqa 0x40(%rsp), %xmm0
pcmpeqb 0x7b58(%rip), %xmm0     # 0xd760
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x5abd
movq %r15, %rdi
leaq 0x7c1a(%rip), %rsi      # 0xd83b
pushq $0x18
popq %rdx
callq 0x1140
testl %eax, %eax
je 0x5abd
movq %r15, %rdi
callq 0x1372
movq 0x10(%rsp), %rbx
movq %rax, 0x18(%rbx)
leaq 0x1040(%rsp), %rdi
callq 0x12dc
movq %rax, 0x20(%rsp)
movq 0x18(%rbx), %rdi
callq 0x1372
movq %rax, %rcx
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x5c70
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5c74
leaq 0x1(%rcx), %rdi
movq 0x20(%rsp), %rax
decl %eax
movl %eax, 0x30(%rsp)
movq %rcx, 0x8(%rsp)
callq 0x1393
leaq 0x440(%rsp), %rdi
leaq 0x7bbb(%rip), %rsi      # 0xd853
movl 0x30(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x8(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x5cbb
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5cbf
leaq 0x1(%rcx), %rdi
callq 0x1393
movq 0x8(%rsp), %rcx
movq %rax, 0x38(%rsp)
movzbl (%rcx), %eax
cmpl $0x40, %eax
leaq 0xc40(%rsp), %rbx
je 0x5ce6
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5cea
leaq 0x1(%rcx), %rdi
callq 0x1393
movq %rbx, %rdi
leaq 0x7b73(%rip), %rsi      # 0xd86c
movq 0x38(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x8(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x5d1d
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x5d23
movq %rcx, %rdi
incq %rdi
callq 0x1393
leaq 0x840(%rsp), %rdi
leaq 0x7b4f(%rip), %rsi      # 0xd886
movl 0x30(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movq 0x8(%rsp), %rdi
callq 0x1030
leaq 0x1040(%rsp), %rbx
movq %rbx, %rdi
callq 0x13f8
movq %rbx, %rdi
callq 0x1372
movq 0x10(%rsp), %rbx
movq %rax, 0x20(%rbx)
movq 0x20(%rsp), %rax
cltd
pushq $0x4
popq %rcx
idivl %ecx
leaq 0x440(%rsp), %rdi
jmp 0x5edc
movl 0x1c(%rsp), %eax
movl %eax, 0x40(%rbx)
movl $0x4, 0x10(%rbx)
movq %r13, %rdi
movq %r15, %rsi
callq 0x1ec1
movq 0x40(%rsp), %rax
movabsq $0x7478656f72657a, %rcx # imm = 0x7478656F72657A
cmpq %rcx, %rax
je 0x5dba
cmpq %rbp, %rax
jne 0x5dc5
movq %r13, %rdi
movq %r15, %rsi
callq 0xc4ad
movq %r15, %rdi
callq 0x1372
movq %rax, 0x18(%rbx)
leaq 0x1040(%rsp), %rdi
callq 0x12dc
movq %rax, 0x8(%rsp)
movb 0x40(%rsp), %cl
cmpb $0x40, %cl
movq %r15, %rdi
leaq 0x41(%rsp), %rdx
cmoveq %rdx, %rdi
leal -0x1(%rax), %ebx
movl %ebx, 0x20(%rsp)
cmpb $0x25, %cl
cmoveq %rdx, %rdi
callq 0x1393
leaq 0x440(%rsp), %rdi
leaq 0x7a3b(%rip), %rsi      # 0xd853
movl %ebx, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
leaq 0x41(%rsp), %rbx
cmoveq %rbx, %rdi
cmpb $0x25, %al
cmoveq %rbx, %rdi
callq 0x1393
movb 0x40(%rsp), %cl
cmpb $0x40, %cl
movq %r15, %rdi
cmoveq %rbx, %rdi
movq %rax, 0x30(%rsp)
cmpb $0x25, %cl
cmoveq %rbx, %rdi
callq 0x1393
leaq 0xc40(%rsp), %rdi
leaq 0x79fd(%rip), %rsi      # 0xd86c
movq 0x30(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
cmoveq %rbx, %rdi
cmpb $0x25, %al
cmoveq %rbx, %rdi
callq 0x1393
leaq 0x840(%rsp), %rdi
movq 0x10(%rsp), %rbx
leaq 0x79dc(%rip), %rsi      # 0xd886
movl 0x20(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
leaq 0x1040(%rsp), %rdi
callq 0x1372
leaq 0x440(%rsp), %rdi
movq %rax, 0x20(%rbx)
movq 0x8(%rsp), %rax
cltd
pushq $0x8
popq %rcx
idivl %ecx
movl %eax, 0x44(%rbx)
incl 0x1c(%rsp)
callq 0x1372
movq %rax, 0x28(%rbx)
leaq 0xc40(%rsp), %rdi
callq 0x1372
movq %rax, 0x30(%rbx)
leaq 0x840(%rsp), %rdi
callq 0x1372
movq %rax, 0x38(%rbx)
movq %r13, %rdi
movq %r15, %rsi
callq 0xc4ad
movzwl 0x40(%rsp), %eax
cmpl $0x29, %eax
je 0x5a4e
cmpl $0x2c, %eax
jne 0x5f0e
jmp 0x5a4e
cmpl $0x6, %eax
jne 0x61ce
callq 0x5574
movq %rax, %rbx
leaq 0x30(%r13), %rdi
callq 0x1372
movq %rax, 0x18(%rbx)
movq %r13, 0x28(%rsp)
leaq 0x3c34(%r13), %rdi
callq 0x1372
movq %rax, 0x20(%rbx)
orl $-0x1, 0x40(%rbx)
movl $0x1, 0x10(%rbx)
movq %rbx, 0x8(%rsp)
movq 0x18(%rbx), %rdi
callq 0x1372
movq %rax, %r13
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x5f90
movq %r13, %rdi
cmpl $0x25, %eax
jne 0x5f94
leaq 0x1(%r13), %rdi
callq 0x1393
leaq 0x440(%rsp), %rdi
leaq 0x77f9(%rip), %rsi      # 0xd7a1
movq %rax, %rdx
xorl %eax, %eax
callq 0x11a0
movzbl (%r13), %eax
cmpl $0x40, %eax
leaq 0xc40(%rsp), %rbx
je 0x5fcc
movq %r13, %rdi
cmpl $0x25, %eax
jne 0x5fd0
leaq 0x1(%r13), %rdi
callq 0x1393
movq %rax, 0x10(%rsp)
movzbl (%r13), %eax
cmpl $0x40, %eax
je 0x5fec
movq %r13, %rdi
cmpl $0x25, %eax
jne 0x5ff0
leaq 0x1(%r13), %rdi
callq 0x1393
movq %rbx, %rdi
leaq 0x77bb(%rip), %rsi      # 0xd7ba
movq 0x10(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11a0
movzbl (%r13), %eax
cmpl $0x40, %eax
je 0x6020
movq %r13, %rdi
cmpl $0x25, %eax
jne 0x6026
movq %r13, %rdi
incq %rdi
callq 0x1393
leaq 0x840(%rsp), %rdi
leaq 0x779a(%rip), %rsi      # 0xd7d4
movq %rax, %rdx
xorl %eax, %eax
callq 0x11a0
movq %r13, %rdi
callq 0x1030
leaq 0x440(%rsp), %rdi
callq 0x1372
movq 0x8(%rsp), %rbx
movq %rax, 0x28(%rbx)
leaq 0xc40(%rsp), %rdi
callq 0x1372
movq %rax, 0x30(%rbx)
leaq 0x840(%rsp), %rdi
callq 0x1372
movq %rax, 0x38(%rbx)
jmp 0x61c2
movq %rcx, %rbx
callq 0x5574
movq %rax, 0x8(%rsp)
movl $0x5, 0x10(%rax)
leaq 0x6434(%r13), %rdi
movq %rdi, 0x10(%rsp)
movq %rbx, %rsi
callq 0x1100
testl %eax, %eax
movq %r13, 0x28(%rsp)
je 0x6168
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x12dc
movl %eax, 0x20(%rsp)
leaq 0x6834(%r13), %rdi
callq 0x1372
movq 0x8(%rsp), %r13
movq %rax, 0x18(%r13)
movq %rbx, %rdi
callq 0x1372
movq %rax, 0x20(%r13)
movl 0x20(%rsp), %esi
movl %esi, %eax
cltd
pushq $0x8
popq %rcx
idivl %ecx
movl %eax, 0x44(%r13)
decl %esi
movl %esi, %edx
leaq 0x440(%rsp), %rbx
movq %rbx, %rdi
leaq 0x7786(%rip), %rsi      # 0xd89c
xorl %eax, %eax
callq 0x11a0
jmp 0x61b6
callq 0x5574
movq %r13, %rbx
movq %rax, %r13
leaq 0x30(%rbx), %rdi
callq 0x1372
movq %rax, 0x18(%r13)
leaq 0x6c34(%rbx), %rdi
callq 0x1372
leaq 0x6eb7(%rip), %rcx      # 0xd004
movq %rax, 0x20(%r13)
movl $0x2, 0x10(%r13)
movq %rbx, %r13
jmp 0x61ce
movq %r13, %rdi
callq 0x1030
jmp 0x61c2
leaq 0x8e34(%rip), %rdi      # 0xefa3
callq 0x1372
movq 0x8(%rsp), %r13
movq %rax, 0x18(%r13)
movq %rbx, %rdi
callq 0x1372
movq %rax, 0x20(%r13)
andl $0x0, 0x44(%r13)
movups 0x7729(%rip), %xmm0     # 0xd8be
movaps %xmm0, 0x440(%rsp)
movdqu 0x7724(%rip), %xmm0     # 0xd8c9
movdqu %xmm0, 0x44b(%rsp)
leaq 0x440(%rsp), %rbx
movq %rbx, %rdi
callq 0x1372
movq %rax, 0x28(%r13)
movq 0x28(%rsp), %r13
leaq 0x6e36(%rip), %rcx      # 0xd004
addq $0x8, %r13
jmp 0x59f8
xorl %eax, %eax
addq $0x1448, %rsp           # imm = 0x1448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq