// File: /workspace/github_c_makefile_star2_O1/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 0x8c9e(%rip), %rdi      # 0xe9ca
callq 0x1070
movb $0x0, 0x440(%rsp)
leaq 0xe400(%rip), %rax      # 0x14140
movq (%rax), %rbx
testq %rbx, %rbx
je 0x65a4
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 0x62ea
cmpl $0x9, %eax
je 0x64e4
cmpl $0x12, %eax
je 0x6443
cmpl $0xf, %eax
jne 0x6597
movq %rbx, 0x18(%rsp)
leaq 0x1430(%rbx), %rdi
callq 0x1395
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
callq 0xcc26
cmpb $0x0, (%rbx)
je 0x6521
movq %rbx, %rdi
movq %r15, %rsi
callq 0x201a
cmpb $0x0, 0x40(%rsp)
je 0x6521
cmpw $0x29, 0x40(%rsp)
je 0x6521
leaq 0x840(%rsp), %rdi
movq %r15, %rsi
callq 0x1060
movq %r15, %rdi
callq 0x3f2a
movl %eax, 0x10(%rsp)
callq 0x58c4
movq %rax, %rcx
cmpl $0x0, 0x10(%rsp)
movq %rax, 0x8(%rsp)
je 0x6127
movl $0x4, 0x10(%rcx)
movl 0x24(%rsp), %eax
movl %eax, 0x40(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcc26
movl 0x40(%rsp), %eax
xorl %r14d, %eax
movzwl 0x44(%rsp), %ecx
xorl $0x6e, %ecx
orl %eax, %ecx
jne 0x5e60
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcc26
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcc26
movq 0x40(%rsp), %rax
cmpq %r13, %rax
je 0x5e2c
cmpq %r12, %rax
je 0x5e2c
movl 0x40(%rsp), %ecx
xorl %ebp, %ecx
movzwl 0x44(%rsp), %edx
xorl $0x67, %edx
orl %ecx, %edx
je 0x5e2c
movl 0x40(%rsp), %ecx
movl $0x61767962, %edx       # imm = 0x61767962
xorl %edx, %ecx
movzwl 0x44(%rsp), %edx
xorl $0x6c, %edx
orl %ecx, %edx
je 0x5e2c
movl 0x40(%rsp), %ecx
movl $0x74657273, %edx       # imm = 0x74657273
xorl %edx, %ecx
movzbl 0x44(%rsp), %edx
orl %ecx, %edx
je 0x5e2c
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 0x5e2c
movb %dl, %cl
testl %ecx, %ecx
je 0x5e2c
movq 0x40(%rsp), %rax
movabsq $0x7275747061636f6e, %rcx # imm = 0x7275747061636F6E
xorq %rcx, %rax
movzwl 0x48(%rsp), %ecx
xorq $0x65, %rcx
orq %rax, %rcx
je 0x5e2c
movl 0x40(%rsp), %eax
movl $0x7473656e, %ecx       # imm = 0x7473656E
xorl %ecx, %eax
movzbl 0x44(%rsp), %ecx
orl %eax, %ecx
je 0x5e2c
movq 0x40(%rsp), %rax
movabsq $0x796c6e6f64616572, %rcx # imm = 0x796C6E6F64616572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5e2c
movq 0x40(%rsp), %rax
movabsq $0x656e6f6e64616572, %rcx # imm = 0x656E6F6E64616572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5e2c
movq 0x40(%rsp), %rax
movabsq $0x64656e7275746572, %rcx # imm = 0x64656E7275746572
xorq %rcx, %rax
movzbl 0x48(%rsp), %ecx
orq %rax, %rcx
je 0x5e2c
movdqa 0x40(%rsp), %xmm0
pcmpeqb 0x87e7(%rip), %xmm0     # 0xe770
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x5e2c
movq 0x50(%rsp), %xmm0
pcmpeqb 0x87da(%rip), %xmm0     # 0xe780
movdqa 0x40(%rsp), %xmm1
pcmpeqb 0x87dc(%rip), %xmm1     # 0xe790
pand %xmm0, %xmm1
pmovmskb %xmm1, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x5e2c
movq %r15, %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x840(%rsp), %rdi
callq 0x12ec
movq %rax, 0x30(%rsp)
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0x1395
movq %rax, %rcx
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x600b
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x600f
leaq 0x1(%rcx), %rdi
movq 0x30(%rsp), %rax
decl %eax
movl %eax, 0x28(%rsp)
movq %rcx, 0x10(%rsp)
callq 0x13b8
leaq 0x440(%rsp), %rdi
leaq 0x8850(%rip), %rsi      # 0xe883
movl 0x28(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movq 0x10(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x6056
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x605a
leaq 0x1(%rcx), %rdi
callq 0x13b8
movq 0x10(%rsp), %rcx
movq %rax, 0x38(%rsp)
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x6079
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x607d
leaq 0x1(%rcx), %rdi
callq 0x13b8
leaq 0x1040(%rsp), %rdi
leaq 0x880b(%rip), %rsi      # 0xe89c
movq 0x38(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movq 0x10(%rsp), %rcx
movzbl (%rcx), %eax
cmpl $0x40, %eax
je 0x60b5
movq %rcx, %rdi
cmpl $0x25, %eax
jne 0x60bb
movq %rcx, %rdi
incq %rdi
callq 0x13b8
leaq 0xc40(%rsp), %rdi
leaq 0x87e7(%rip), %rsi      # 0xe8b6
movl 0x28(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movq 0x10(%rsp), %rdi
callq 0x1030
leaq 0x840(%rsp), %rdi
callq 0x142c
leaq 0x840(%rsp), %rdi
callq 0x1395
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 0x6286
movl 0x24(%rsp), %eax
movl %eax, 0x40(%rcx)
movl $0x4, 0x10(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x201a
movq 0x40(%rsp), %rax
cmpq %r12, %rax
je 0x614f
cmpq %r13, %rax
jne 0x615a
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcc26
movq %r15, %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x840(%rsp), %rdi
callq 0x12ec
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 0x13b8
leaq 0x440(%rsp), %rdi
leaq 0x86d2(%rip), %rsi      # 0xe883
movl 0x10(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
leaq 0x41(%rsp), %rcx
cmoveq %rcx, %rdi
cmpb $0x25, %al
cmoveq %rcx, %rdi
callq 0x13b8
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 0x13b8
leaq 0x1040(%rsp), %rdi
leaq 0x868d(%rip), %rsi      # 0xe89c
movq 0x28(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movb 0x40(%rsp), %al
cmpb $0x40, %al
movq %r15, %rdi
leaq 0x41(%rsp), %rcx
cmoveq %rcx, %rdi
cmpb $0x25, %al
cmoveq %rcx, %rdi
callq 0x13b8
leaq 0xc40(%rsp), %rdi
leaq 0x866c(%rip), %rsi      # 0xe8b6
movl 0x10(%rsp), %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
leaq 0x840(%rsp), %rdi
callq 0x1395
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 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x28(%rcx)
leaq 0x1040(%rsp), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x30(%rcx)
leaq 0xc40(%rsp), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x38(%rcx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcc26
movzwl 0x40(%rsp), %eax
cmpl $0x2c, %eax
je 0x5dbf
cmpl $0x29, %eax
jne 0x62c7
jmp 0x5dbf
cmpl $0x6, %eax
jne 0x6597
callq 0x58c4
movq %rax, 0x8(%rsp)
leaq 0x30(%rbx), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
movq %rbx, 0x18(%rsp)
leaq 0x3c34(%rbx), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x20(%rcx)
movl $0xffffffff, 0x40(%rcx) # imm = 0xFFFFFFFF
movl $0x1, 0x10(%rcx)
movq 0x18(%rcx), %rdi
callq 0x1395
movq %rax, %rbx
movzbl (%rax), %eax
cmpl $0x40, %eax
je 0x6353
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x6357
leaq 0x1(%rbx), %rdi
callq 0x13b8
leaq 0x440(%rsp), %rdi
leaq 0x8466(%rip), %rsi      # 0xe7d1
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b0
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x6385
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x6389
leaq 0x1(%rbx), %rdi
callq 0x13b8
movq %rax, 0x10(%rsp)
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x63a3
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x63a7
leaq 0x1(%rbx), %rdi
callq 0x13b8
leaq 0x1040(%rsp), %rdi
leaq 0x842f(%rip), %rsi      # 0xe7ea
movq 0x10(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x11b0
movzbl (%rbx), %eax
cmpl $0x40, %eax
je 0x63da
movq %rbx, %rdi
cmpl $0x25, %eax
jne 0x63e0
movq %rbx, %rdi
incq %rdi
callq 0x13b8
leaq 0xc40(%rsp), %rdi
leaq 0x8410(%rip), %rsi      # 0xe804
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b0
movq %rbx, %rdi
callq 0x1030
leaq 0x440(%rsp), %rdi
callq 0x1395
movq 0x8(%rsp), %rbx
movq %rax, 0x28(%rbx)
leaq 0x1040(%rsp), %rdi
callq 0x1395
movq %rax, 0x30(%rbx)
leaq 0xc40(%rsp), %rdi
callq 0x1395
movq %rax, 0x38(%rbx)
jmp 0x6529
callq 0x58c4
movq %rax, 0x8(%rsp)
movl $0x5, 0x10(%rax)
leaq 0x6434(%rbx), %rdi
movq %rdi, 0x10(%rsp)
leaq 0x7b9d(%rip), %rsi      # 0xe004
callq 0x1110
testl %eax, %eax
je 0x6530
movq 0x10(%rsp), %rdi
callq 0x12ec
movq %rbx, 0x18(%rsp)
movl %eax, %ebx
movq 0x18(%rsp), %rax
leaq 0x6834(%rax), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
movq 0x10(%rsp), %rdi
callq 0x1395
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 0x83fb(%rip), %rsi      # 0xe8cc
movl %ebx, %edx
movq 0x18(%rsp), %rbx
xorl %eax, %eax
callq 0x11b0
jmp 0x6581
callq 0x58c4
movq %rbx, 0x18(%rsp)
movq %rax, %rbx
movq 0x18(%rsp), %rax
leaq 0x30(%rax), %rdi
callq 0x1395
movq %rax, 0x18(%rbx)
movq 0x18(%rsp), %rax
leaq 0x6c34(%rax), %rdi
callq 0x1395
movq %rax, 0x20(%rbx)
movl $0x2, 0x10(%rbx)
jmp 0x6529
movq %rbx, %rdi
callq 0x1030
movq 0x18(%rsp), %rbx
jmp 0x6597
leaq 0x9a98(%rip), %rdi      # 0xffcf
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x18(%rcx)
leaq 0x7ab8(%rip), %rdi      # 0xe004
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x20(%rcx)
movl $0x0, 0x44(%rcx)
movups 0x8386(%rip), %xmm0     # 0xe8ee
movaps %xmm0, 0x440(%rsp)
movdqu 0x8381(%rip), %xmm0     # 0xe8f9
movdqu %xmm0, 0x44b(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x1395
movq 0x8(%rsp), %rcx
movq %rax, 0x28(%rcx)
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
jne 0x5d78
xorl %eax, %eax
addq $0x1448, %rsp           # imm = 0x1448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq