// File: akshayrajput[P]ARMV8_Simulator/./instructions.cpp
// Function: ADD(int, int, int, int, int)
void ADD(int sf, int sw,int RD,int RN,int immRM)
{
	
	//ADD stub
	printf("[log] - add instructions\n");

	assert(RD >= 0 && RD <= 31);
	assert(RN >= 0 && RN <= 31);
	
	//TODO - Add shifted operands also
	if(sf == 1 && sw == 0)
	{
		printf("[log] - adding 64 bit immediate\n");
		uint64_t result = R[RN].getData() + immRM ;
		
		if(result < R[RN].getData() )
		{
			printf("Addition overflow!!\n");
			return;
		}

		R[RD].setData(result);

	}
	else if(sf == 0 && sw == 0)
	{
		printf("[log] - adding 32 bit immediate\n");
		uint32_t result = R[RN].getLowerData() + immRM ;
		
		if(result < R[RN].getLowerData() )
		{
			printf("Addition overflow!!\n");
			return;
		}

		R[RD].setLowerData(result);

	}
	else if(sf == 1 && sw == 1)
	{
		printf("[log] - adding 64 bit register\n");
		assert(immRM >= 0 && immRM <= 31);
		uint64_t result = R[RN].getData() + R[immRM].getData() ;
		
		if(result < R[RN].getData() )
		{
			printf("Addition overflow!!\n");
			return;
		}

		R[RD].setData(result);

	}
	else if(sf == 0 && sw == 1)
	{
		printf("[log] - adding 32 bit register\n");
		assert(immRM >= 0 && immRM <= 31);
		uint32_t result = R[RN].getLowerData() + R[immRM].getData() ;
		
		if(result < R[RN].getLowerData() )
		{
			printf("Addition overflow!!\n");
			return;
		}

		R[RD].setLowerData(result);

	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl %edx, -0xc(%rbp)
movl %ecx, -0x10(%rbp)
movl %r8d, -0x14(%rbp)
leaq 0x98b8(%rip), %rdi      # 0xb177
movb $0x0, %al
callq 0x1030
xorl %eax, %eax
cmpl $0x0, -0xc(%rbp)
movb %al, -0x35(%rbp)
jl 0x18db
cmpl $0x1f, -0xc(%rbp)
setle %al
movb %al, -0x35(%rbp)
movb -0x35(%rbp), %al
testb $0x1, %al
jne 0x18e4
jmp 0x18e6
jmp 0x1905
leaq 0x98a4(%rip), %rdi      # 0xb191
leaq 0x975b(%rip), %rsi      # 0xb04f
movl $0x97, %edx
leaq 0x98a5(%rip), %rcx      # 0xb1a5
callq 0x1060
xorl %eax, %eax
cmpl $0x0, -0x10(%rbp)
movb %al, -0x36(%rbp)
jl 0x191a
cmpl $0x1f, -0x10(%rbp)
setle %al
movb %al, -0x36(%rbp)
movb -0x36(%rbp), %al
testb $0x1, %al
jne 0x1923
jmp 0x1925
jmp 0x1944
leaq 0x989b(%rip), %rdi      # 0xb1c7
leaq 0x971c(%rip), %rsi      # 0xb04f
movl $0x98, %edx
leaq 0x9866(%rip), %rcx      # 0xb1a5
callq 0x1060
cmpl $0x1, -0x4(%rbp)
jne 0x19e6
cmpl $0x0, -0x8(%rbp)
jne 0x19e6
leaq 0x987c(%rip), %rdi      # 0xb1db
movb $0x0, %al
callq 0x1030
movslq -0x10(%rbp), %rax
leaq 0xc76f(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movslq -0x14(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
movslq -0x10(%rbp), %rax
leaq 0xc745(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movq %rax, %rcx
movq -0x40(%rbp), %rax
cmpq %rcx, %rax
jae 0x19c6
leaq 0x9842(%rip), %rdi      # 0xb1fc
movb $0x0, %al
callq 0x1030
jmp 0x1c74
movslq -0xc(%rbp), %rax
leaq 0xc70f(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0xa710
jmp 0x1c74
cmpl $0x0, -0x4(%rbp)
jne 0x1a7d
cmpl $0x0, -0x8(%rbp)
jne 0x1a7d
leaq 0x9810(%rip), %rdi      # 0xb211
movb $0x0, %al
callq 0x1030
movslq -0x10(%rbp), %rax
leaq 0xc6cd(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6e0
addl -0x14(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x44(%rbp)
movslq -0x10(%rbp), %rax
leaq 0xc6aa(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6e0
movl %eax, %ecx
movl -0x44(%rbp), %eax
cmpl %ecx, %eax
jae 0x1a5e
leaq 0x97aa(%rip), %rdi      # 0xb1fc
movb $0x0, %al
callq 0x1030
jmp 0x1c74
movslq -0xc(%rbp), %rax
leaq 0xc677(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
movl -0x24(%rbp), %esi
callq 0xa730
jmp 0x1c72
cmpl $0x1, -0x4(%rbp)
jne 0x1b7c
cmpl $0x1, -0x8(%rbp)
jne 0x1b7c
leaq 0x979a(%rip), %rdi      # 0xb232
movb $0x0, %al
callq 0x1030
xorl %eax, %eax
cmpl $0x0, -0x14(%rbp)
movb %al, -0x45(%rbp)
jl 0x1ab4
cmpl $0x1f, -0x14(%rbp)
setle %al
movb %al, -0x45(%rbp)
movb -0x45(%rbp), %al
testb $0x1, %al
jne 0x1abd
jmp 0x1abf
jmp 0x1ade
leaq 0x978c(%rip), %rdi      # 0xb252
leaq 0x9582(%rip), %rsi      # 0xb04f
movl $0xba, %edx
leaq 0x96cc(%rip), %rcx      # 0xb1a5
callq 0x1060
movslq -0x10(%rbp), %rax
leaq 0xc5f7(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movq %rax, -0x58(%rbp)
movslq -0x14(%rbp), %rax
leaq 0xc5dc(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movq %rax, %rcx
movq -0x58(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movslq -0x10(%rbp), %rax
leaq 0xc5af(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movq %rax, %rcx
movq -0x50(%rbp), %rax
cmpq %rcx, %rax
jae 0x1b5c
leaq 0x96ac(%rip), %rdi      # 0xb1fc
movb $0x0, %al
callq 0x1030
jmp 0x1c74
movslq -0xc(%rbp), %rax
leaq 0xc579(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
movq -0x30(%rbp), %rsi
callq 0xa710
jmp 0x1c70
cmpl $0x0, -0x4(%rbp)
jne 0x1c6e
cmpl $0x1, -0x8(%rbp)
jne 0x1c6e
leaq 0x96d5(%rip), %rdi      # 0xb26c
movb $0x0, %al
callq 0x1030
xorl %eax, %eax
cmpl $0x0, -0x14(%rbp)
movb %al, -0x59(%rbp)
jl 0x1bb3
cmpl $0x1f, -0x14(%rbp)
setle %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %al
testb $0x1, %al
jne 0x1bbc
jmp 0x1bbe
jmp 0x1bdd
leaq 0x968d(%rip), %rdi      # 0xb252
leaq 0x9483(%rip), %rsi      # 0xb04f
movl $0xc9, %edx
leaq 0x95cd(%rip), %rcx      # 0xb1a5
callq 0x1060
movslq -0x10(%rbp), %rax
leaq 0xc4f8(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6e0
movl %eax, %eax
movq %rax, -0x68(%rbp)
movslq -0x14(%rbp), %rax
leaq 0xc4db(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6c0
movq %rax, %rcx
movq -0x68(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x60(%rbp)
movslq -0x10(%rbp), %rax
leaq 0xc4b1(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
callq 0xa6e0
movl %eax, %ecx
movl -0x60(%rbp), %eax
cmpl %ecx, %eax
jae 0x1c54
leaq 0x95b1(%rip), %rdi      # 0xb1fc
movb $0x0, %al
callq 0x1030
jmp 0x1c74
movslq -0xc(%rbp), %rax
leaq 0xc481(%rip), %rdi      # 0xe0e0
shlq $0x3, %rax
addq %rax, %rdi
movl -0x34(%rbp), %esi
callq 0xa730
jmp 0x1c70
jmp 0x1c72
jmp 0x1c74
addq $0x70, %rsp
popq %rbp
retq
nopw (%rax,%rax)