// File: AndrewAlbert[P]Compiler-Theory/SourceCode/codeGenerator.cpp
// Function: codeGenerator::mm2reg[abi:cxx11](int, int, int, bool, int, bool, int, bool)
string codeGenerator::mm2reg(int memType, int memSize, int FPoffset, bool isGlobal, int index, bool indirect, int indirect_type, bool useSP){
	if( !ShouldGenerate() ) return "";
	string reg, mem, pointer;
	
	// Set comment to indicate if this is Global/Local MM to Reg
	if( isGlobal ) comment("Global MM to Reg");
	else comment("Local MM to Reg");

	// Get either the FP or SP register based on 
	if(useSP) pointer = "SP_reg";
	else pointer = "FP_reg";

	// Ensure source size is at least 1 for loops
	if( memSize == 0 ) memSize++;

	// Indirect off of the top register
	if( indirect ){
		string indirect_reg = popStack('E', indirect_type);
		comment("indirect off " + indirect_reg);
		fprintf( oFile, "   TP_reg = %s + %d;\n", pointer.c_str(), FPoffset );
		
		reg = newRegister(memType);
		pushStack(reg, 'E', memType);
		fprintf( oFile, "   %s = MM[TP_reg + %s];\n", reg.c_str(), indirect_reg.c_str() );
	} 
	else{
		if( index < 0){
			for( index = 0; index < memSize; index++ ){
				reg = newRegister(memType);
				pushStack(reg, 'E', memType);
			
				if( isGlobal ) mem = "MM[" + to_string(FPoffset + index) + "]";
				else mem = "MM[" + pointer + " + " + to_string(FPoffset + index) + "]";
			
				if( memType == TYPE_FLOAT) fprintf( oFile, "   memcpy( &%s, &%s, sizeof(int) );\n", reg.c_str(), mem.c_str() );
				else fprintf( oFile, "   %s = %s;\n", reg.c_str(), mem.c_str() );
			}
		}
		else{
			reg = newRegister(memType);
			pushStack(reg, 'E', memType);
		
			if( isGlobal ) mem = "MM[" + to_string(FPoffset + index) + "]";
			else mem = "MM[" + pointer + " + " + to_string(FPoffset + index) + "]";
		
			if( memType == TYPE_FLOAT) fprintf( oFile, "   memcpy( &%s, &%s, sizeof(int) );\n", reg.c_str(), mem.c_str() );
			else fprintf( oFile, "   %s = %s;\n", reg.c_str(), mem.c_str() );
		}
	}
	return "";
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movl %r9d, %eax
movl %ecx, -0x408(%rbp)
movl %edx, -0x404(%rbp)
movq %rsi, %r9
movl -0x408(%rbp), %esi
movq %rdi, %r10
movl -0x404(%rbp), %edi
movq %r10, -0x400(%rbp)
movb %al, %dl
movq %r10, %rax
movq %rax, -0x3f8(%rbp)
movb 0x28(%rbp), %al
movl 0x20(%rbp), %ecx
movb 0x18(%rbp), %cl
movl 0x10(%rbp), %r11d
movq %r10, -0x8(%rbp)
movq %r9, -0x10(%rbp)
movl %edi, -0x14(%rbp)
movl %esi, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
andb $0x1, %dl
movb %dl, -0x1d(%rbp)
andb $0x1, %cl
movb %cl, -0x1e(%rbp)
andb $0x1, %al
movb %al, -0x1f(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x3f0(%rbp)
callq 0x19590
testb $0x1, %al
jne 0x1c837
leaq -0x20(%rbp), %rdi
movq %rdi, -0x410(%rbp)
callq 0x3430
movq -0x400(%rbp), %rdi
movq -0x410(%rbp), %rdx
leaq 0xa479(%rip), %rsi      # 0x26c81
callq 0x62d0
jmp 0x1c80f
leaq -0x20(%rbp), %rdi
callq 0x32e0
jmp 0x1d2cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x32e0
jmp 0x1d2dc
leaq -0x50(%rbp), %rdi
callq 0x3370
leaq -0x70(%rbp), %rdi
callq 0x3370
leaq -0x90(%rbp), %rdi
callq 0x3370
testb $0x1, -0x1d(%rbp)
je 0x1c8d9
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0x3430
movq -0x418(%rbp), %rdx
leaq 0xa986(%rip), %rsi      # 0x27202
leaq -0xb0(%rbp), %rdi
callq 0x62d0
jmp 0x1c88a
movq -0x3f0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
xorl %edx, %edx
callq 0x19bb0
leaq -0xb0(%rbp), %rdi
callq 0x31a0
leaq -0xb1(%rbp), %rdi
callq 0x32e0
jmp 0x1c954
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0xb1(%rbp), %rdi
callq 0x32e0
jmp 0x1d2ac
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x420(%rbp)
callq 0x3430
movq -0x420(%rbp), %rdx
leaq 0xa919(%rip), %rsi      # 0x27213
leaq -0xd8(%rbp), %rdi
callq 0x62d0
jmp 0x1c908
movq -0x3f0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
xorl %edx, %edx
callq 0x19bb0
leaq -0xd8(%rbp), %rdi
callq 0x31a0
leaq -0xd9(%rbp), %rdi
callq 0x32e0
jmp 0x1c954
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0xd9(%rbp), %rdi
callq 0x32e0
jmp 0x1d2ac
testb $0x1, -0x1f(%rbp)
je 0x1c982
leaq 0xa378(%rip), %rsi      # 0x26cd9
leaq -0x90(%rbp), %rdi
callq 0x3360
jmp 0x1c96f
jmp 0x1c999
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1d2ac
leaq 0xa349(%rip), %rsi      # 0x26cd2
leaq -0x90(%rbp), %rdi
callq 0x3360
jmp 0x1c997
jmp 0x1c999
cmpl $0x0, -0x18(%rbp)
jne 0x1c9a8
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
testb $0x1, -0x1e(%rbp)
je 0x1cb71
movq -0x3f0(%rbp), %rsi
movl 0x20(%rbp), %ecx
leaq -0x100(%rbp), %rdi
movl $0x45, %edx
callq 0x1a7a0
jmp 0x1c9cf
leaq 0xa84d(%rip), %rsi      # 0x27223
leaq -0x120(%rbp), %rdi
leaq -0x100(%rbp), %rdx
callq 0x124f0
jmp 0x1c9eb
movq -0x3f0(%rbp), %rdi
leaq -0x120(%rbp), %rsi
movq %rsi, -0x438(%rbp)
xorl %edx, %edx
movl %edx, -0x424(%rbp)
callq 0x19bb0
movq -0x438(%rbp), %rdi
callq 0x31a0
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x430(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x3120
movq -0x430(%rbp), %rdi
movq %rax, %rdx
movl -0x424(%rbp), %eax
movl -0x1c(%rbp), %ecx
leaq 0xa7dd(%rip), %rsi      # 0x27231
callq 0x3380
movq -0x3f0(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0x140(%rbp), %rdi
callq 0x1baf0
jmp 0x1ca71
leaq -0x50(%rbp), %rdi
movq %rdi, -0x440(%rbp)
leaq -0x140(%rbp), %rsi
movq %rsi, -0x448(%rbp)
callq 0x3340
movq -0x448(%rbp), %rdi
callq 0x31a0
movq -0x440(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x3130
jmp 0x1cab0
movq -0x3f0(%rbp), %rdi
movl -0x14(%rbp), %ecx
leaq -0x160(%rbp), %rsi
movl $0x45, %edx
callq 0x1a6b0
jmp 0x1cacd
leaq -0x160(%rbp), %rdi
callq 0x31a0
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x458(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3120
movq %rax, -0x450(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x3120
movq -0x458(%rbp), %rdi
movq -0x450(%rbp), %rdx
movq %rax, %rcx
leaq 0xa725(%rip), %rsi      # 0x27247
movb $0x0, %al
callq 0x3380
leaq -0x100(%rbp), %rdi
callq 0x31a0
jmp 0x1d239
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1cb60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x31a0
leaq -0x100(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
cmpl $0x0, 0x10(%rbp)
jge 0x1ceec
movl $0x0, 0x10(%rbp)
movl 0x10(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1cee7
movq -0x3f0(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0x180(%rbp), %rdi
callq 0x1baf0
jmp 0x1cba6
leaq -0x50(%rbp), %rdi
movq %rdi, -0x460(%rbp)
leaq -0x180(%rbp), %rsi
movq %rsi, -0x468(%rbp)
callq 0x3340
movq -0x468(%rbp), %rdi
callq 0x31a0
movq -0x460(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
callq 0x3130
jmp 0x1cbe5
movq -0x3f0(%rbp), %rdi
movl -0x14(%rbp), %ecx
leaq -0x1a0(%rbp), %rsi
movl $0x45, %edx
callq 0x1a6b0
jmp 0x1cc02
leaq -0x1a0(%rbp), %rdi
callq 0x31a0
testb $0x1, -0x1d(%rbp)
je 0x1ccf3
movl -0x1c(%rbp), %esi
movl 0x10(%rbp), %eax
addl %eax, %esi
leaq -0x200(%rbp), %rdi
callq 0x123d0
jmp 0x1cc2e
leaq 0xa62c(%rip), %rsi      # 0x27261
leaq -0x1e0(%rbp), %rdi
leaq -0x200(%rbp), %rdx
callq 0x12380
jmp 0x1cc4a
leaq 0x86dd(%rip), %rdx      # 0x2532e
leaq -0x1c0(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x12330
jmp 0x1cc66
leaq -0x70(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x3340
leaq -0x1c0(%rbp), %rdi
callq 0x31a0
leaq -0x1e0(%rbp), %rdi
callq 0x31a0
leaq -0x200(%rbp), %rdi
callq 0x31a0
jmp 0x1ce32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1cce2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x31a0
leaq -0x200(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
leaq 0xa567(%rip), %rsi      # 0x27261
leaq -0x280(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x124f0
jmp 0x1cd0f
leaq 0xa54f(%rip), %rdx      # 0x27265
leaq -0x260(%rbp), %rdi
leaq -0x280(%rbp), %rsi
callq 0x12330
jmp 0x1cd2b
movl -0x1c(%rbp), %esi
movl 0x10(%rbp), %eax
addl %eax, %esi
leaq -0x2a0(%rbp), %rdi
callq 0x123d0
jmp 0x1cd41
leaq -0x240(%rbp), %rdi
leaq -0x260(%rbp), %rsi
leaq -0x2a0(%rbp), %rdx
callq 0x12990
jmp 0x1cd5d
leaq 0x85ca(%rip), %rdx      # 0x2532e
leaq -0x220(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x12330
jmp 0x1cd79
leaq -0x70(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x3340
leaq -0x220(%rbp), %rdi
callq 0x31a0
leaq -0x240(%rbp), %rdi
callq 0x31a0
leaq -0x2a0(%rbp), %rdi
callq 0x31a0
leaq -0x260(%rbp), %rdi
callq 0x31a0
leaq -0x280(%rbp), %rdi
callq 0x31a0
jmp 0x1ce32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1ce21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1ce15
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1ce09
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x31a0
leaq -0x2a0(%rbp), %rdi
callq 0x31a0
leaq -0x260(%rbp), %rdi
callq 0x31a0
leaq -0x280(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
cmpl $0x10b, -0x14(%rbp)     # imm = 0x10B
jne 0x1ce8a
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x478(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3120
movq %rax, -0x470(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3120
movq -0x478(%rbp), %rdi
movq -0x470(%rbp), %rdx
movq %rax, %rcx
leaq 0xa3e8(%rip), %rsi      # 0x27269
movb $0x0, %al
callq 0x3380
jmp 0x1ced7
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x488(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3120
movq %rax, -0x480(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3120
movq -0x488(%rbp), %rdi
movq -0x480(%rbp), %rdx
movq %rax, %rcx
leaq 0xa2b8(%rip), %rsi      # 0x27188
movb $0x0, %al
callq 0x3380
jmp 0x1ced9
movl 0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rbp)
jmp 0x1cb82
jmp 0x1d237
movq -0x3f0(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0x2c0(%rbp), %rdi
callq 0x1baf0
jmp 0x1cf04
leaq -0x50(%rbp), %rdi
movq %rdi, -0x490(%rbp)
leaq -0x2c0(%rbp), %rsi
movq %rsi, -0x498(%rbp)
callq 0x3340
movq -0x498(%rbp), %rdi
callq 0x31a0
movq -0x490(%rbp), %rsi
leaq -0x2e0(%rbp), %rdi
callq 0x3130
jmp 0x1cf43
movq -0x3f0(%rbp), %rdi
movl -0x14(%rbp), %ecx
leaq -0x2e0(%rbp), %rsi
movl $0x45, %edx
callq 0x1a6b0
jmp 0x1cf60
leaq -0x2e0(%rbp), %rdi
callq 0x31a0
testb $0x1, -0x1d(%rbp)
je 0x1d051
movl -0x1c(%rbp), %esi
movl 0x10(%rbp), %eax
addl %eax, %esi
leaq -0x340(%rbp), %rdi
callq 0x123d0
jmp 0x1cf8c
leaq 0xa2ce(%rip), %rsi      # 0x27261
leaq -0x320(%rbp), %rdi
leaq -0x340(%rbp), %rdx
callq 0x12380
jmp 0x1cfa8
leaq 0x837f(%rip), %rdx      # 0x2532e
leaq -0x300(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x12330
jmp 0x1cfc4
leaq -0x70(%rbp), %rdi
leaq -0x300(%rbp), %rsi
callq 0x3340
leaq -0x300(%rbp), %rdi
callq 0x31a0
leaq -0x320(%rbp), %rdi
callq 0x31a0
leaq -0x340(%rbp), %rdi
callq 0x31a0
jmp 0x1d190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x2e0(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1d040
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x31a0
leaq -0x340(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
leaq 0xa209(%rip), %rsi      # 0x27261
leaq -0x3c0(%rbp), %rdi
leaq -0x90(%rbp), %rdx
callq 0x124f0
jmp 0x1d06d
leaq 0xa1f1(%rip), %rdx      # 0x27265
leaq -0x3a0(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0x12330
jmp 0x1d089
movl -0x1c(%rbp), %esi
movl 0x10(%rbp), %eax
addl %eax, %esi
leaq -0x3e0(%rbp), %rdi
callq 0x123d0
jmp 0x1d09f
leaq -0x380(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
leaq -0x3e0(%rbp), %rdx
callq 0x12990
jmp 0x1d0bb
leaq 0x826c(%rip), %rdx      # 0x2532e
leaq -0x360(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x12330
jmp 0x1d0d7
leaq -0x70(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x3340
leaq -0x360(%rbp), %rdi
callq 0x31a0
leaq -0x380(%rbp), %rdi
callq 0x31a0
leaq -0x3e0(%rbp), %rdi
callq 0x31a0
leaq -0x3a0(%rbp), %rdi
callq 0x31a0
leaq -0x3c0(%rbp), %rdi
callq 0x31a0
jmp 0x1d190
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1d17f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1d173
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x1d167
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x31a0
leaq -0x3e0(%rbp), %rdi
callq 0x31a0
leaq -0x3a0(%rbp), %rdi
callq 0x31a0
leaq -0x3c0(%rbp), %rdi
callq 0x31a0
jmp 0x1d2ac
cmpl $0x10b, -0x14(%rbp)     # imm = 0x10B
jne 0x1d1e8
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x4a8(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3120
movq %rax, -0x4a0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3120
movq -0x4a8(%rbp), %rdi
movq -0x4a0(%rbp), %rdx
movq %rax, %rcx
leaq 0xa08a(%rip), %rsi      # 0x27269
movb $0x0, %al
callq 0x3380
jmp 0x1d235
movq -0x3f0(%rbp), %rax
movq 0x308(%rax), %rax
movq %rax, -0x4b8(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3120
movq %rax, -0x4b0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3120
movq -0x4b8(%rbp), %rdi
movq -0x4b0(%rbp), %rdx
movq %rax, %rcx
leaq 0x9f5a(%rip), %rsi      # 0x27188
movb $0x0, %al
callq 0x3380
jmp 0x1d237
jmp 0x1d239
leaq -0x3e1(%rbp), %rdi
movq %rdi, -0x4c0(%rbp)
callq 0x3430
movq -0x400(%rbp), %rdi
movq -0x4c0(%rbp), %rdx
leaq 0x9a20(%rip), %rsi      # 0x26c81
callq 0x62d0
jmp 0x1d268
leaq -0x3e1(%rbp), %rdi
callq 0x32e0
leaq -0x90(%rbp), %rdi
callq 0x31a0
leaq -0x70(%rbp), %rdi
callq 0x31a0
leaq -0x50(%rbp), %rdi
callq 0x31a0
jmp 0x1d2cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x3e1(%rbp), %rdi
callq 0x32e0
leaq -0x90(%rbp), %rdi
callq 0x31a0
leaq -0x70(%rbp), %rdi
callq 0x31a0
leaq -0x50(%rbp), %rdi
callq 0x31a0
jmp 0x1d2dc
movq -0x3f8(%rbp), %rax
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x3420
nopw %cs:(%rax,%rax)