// File: /workspace/github_c_makefile_star2_O0/Encryptr[P]O-plus-plus/opp/ir/ir.c
// Function: oppir_eval_arith
static void oppir_eval_arith(struct OppIr* ir, struct OppIr_Arith* arith)
{
	if (arith->floating) {
		oppir_eval_float_arith(ir, arith);
		return;
	}

	struct Register rhs = oppir_pop_reg(ir);
	BLOCK_REG(rhs.reg);
	struct Register lhs;

	if (!arith->imm)
		lhs = oppir_pop_reg(ir);
	else 
		lhs = rhs;

	UNBLOCK_REG(rhs.reg);

	oppir_check_realloc(ir, 7);

	switch (arith->type)
	{
		case TADD: {
			IR_EMIT(0x48);
			if (arith->imm) {
				if (arith->val.type == IMM_I8) {
					IR_EMIT(0x83);
					IR_EMIT(0xc0 + rhs.reg);
				}
				else {
					if (rhs.reg == REG_RAX)
						IR_EMIT(0x05);
					else {
						IR_EMIT(0x81);
						IR_EMIT(0xc0 + rhs.reg);
					}
				}
			}
			else
				IR_EMIT(0x1);
			break;
		}

		case TMIN: {
			IR_EMIT(0x48);
			if (arith->imm) {
				if (arith->val.type == IMM_I8) {
					IR_EMIT(0x83);
					IR_EMIT(0xe8 + rhs.reg);
				}
				else {
					if (rhs.reg == REG_RAX)
						IR_EMIT(0x2d);
					else {
						IR_EMIT(0x81);
						IR_EMIT(0xe8 + rhs.reg);
					}
				}
			}
			else
				IR_EMIT(0x29);
			break;
		}

		case TMUL: {
			IR_EMIT(0x48);
			if (arith->imm) {
				if (arith->val.imm_i8 == -1) {
					IR_EMIT(0xf7);
					IR_EMIT(0xd8 + rhs.reg);
					goto skip;
				}
				else {
					IR_EMIT(0xc1);
					IR_EMIT(0xe0 + rhs.reg);
					char b = 0;
					while (arith->val.imm_i8 != 1)
						arith->val.imm_i8 >>= 1, b++;
					arith->val.imm_i8 = b;
				}
			}
			else {
				IR_EMIT(0x0f);
				IR_EMIT(0xaf);
				oppir_emit_reg_comb(ir, rhs.reg, lhs.reg);
				goto skip;
			}
			break;
		}

		case TDIV: {
			printf("FIX DIV\n");
			assert(false);
			// if (lhs.reg != REG_RAX) {
			// 	if (regs[REG_RAX].used)
			// 		oppir_spill_reg(ir, REG_RAX);
			// 	oppir_check_realloc(ir, 3);
			// 	IR_EMIT(0x48);
			// 	IR_EMIT(0x89);
			// 	IR_EMIT(0xc8 + ((lhs.reg-1)*8));
			// }
			// if (rhs.reg != REG_RCX) {
			// 	if (regs[REG_RCX].used)
			// 		oppir_spill_reg(ir, REG_RCX);
			// 	oppir_check_realloc(ir, 3);
			// 	IR_EMIT(0x48);
			// 	IR_EMIT(0x89);
			// 	IR_EMIT(0xd1);
			// }
			// if (!arith->unsign) {
			// 	IR_EMIT(0x48);
			// 	IR_EMIT(0x99);
			// 	IR_EMIT(0x48);
			// 	IR_EMIT(0xf7);
			// 	IR_EMIT(0xf9);
			// }
			// else {
			// 	IR_EMIT(0x48);
			// 	IR_EMIT(0xf7);
			// 	IR_EMIT(0xf1);
			// }
			goto skip;
			break;
		}
	}

	if (arith->imm)
		oppir_write_const(ir, &arith->val);
	else
		oppir_emit_reg_comb(ir, lhs.reg, rhs.reg);

	skip:
	oppir_push(ir, lhs);
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x48(%rsp), %rax
testb $0x1, 0x5(%rax)
je 0xb3bd
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0xcec0
jmp 0xb8a4
movq 0x50(%rsp), %rdi
callq 0xc780
movq %rax, 0x38(%rsp)
movq %rdx, 0x40(%rsp)
movl 0x38(%rsp), %eax
movl %eax, %ecx
leaq 0xdd82(%rip), %rax      # 0x19160
shlq $0x4, %rcx
addq %rcx, %rax
movb $0x1, 0xc(%rax)
movq 0x48(%rsp), %rax
testb $0x1, 0x4(%rax)
jne 0xb41e
movq 0x50(%rsp), %rdi
callq 0xc780
movq %rax, 0x18(%rsp)
movq %rdx, 0x20(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xb432
movq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
movl 0x38(%rsp), %eax
shlq $0x4, %rax
leaq 0xdd1f(%rip), %rcx      # 0x19160
movb $0x0, 0xc(%rax,%rcx)
movq 0x50(%rsp), %rdi
movl $0x7, %esi
callq 0x9750
movq 0x48(%rsp), %rax
movl (%rax), %eax
addl $-0x13, %eax
movl %eax, %ecx
movq %rcx, 0x8(%rsp)
subl $0x3, %eax
ja 0xb85c
movq 0x8(%rsp), %rax
leaq 0x8ef5(%rip), %rcx      # 0x14370
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x48, (%rax,%rcx)
movq 0x48(%rsp), %rax
testb $0x1, 0x4(%rax)
je 0xb581
movq 0x48(%rsp), %rax
cmpl $0x4, 0x8(%rax)
jne 0xb50a
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x7d, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xc0, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
jmp 0xb57f
cmpl $0x0, 0x38(%rsp)
jne 0xb533
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x5, (%rax,%rcx)
jmp 0xb57d
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x7f, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xc0, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
jmp 0xb57f
jmp 0xb5a1
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x1, (%rax,%rcx)
jmp 0xb85c
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x48, (%rax,%rcx)
movq 0x48(%rsp), %rax
testb $0x1, 0x4(%rax)
je 0xb6a3
movq 0x48(%rsp), %rax
cmpl $0x4, 0x8(%rax)
jne 0xb62c
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x7d, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xe8, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
jmp 0xb6a1
cmpl $0x0, 0x38(%rsp)
jne 0xb655
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x2d, (%rax,%rcx)
jmp 0xb69f
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x7f, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xe8, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
jmp 0xb6a1
jmp 0xb6c3
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x29, (%rax,%rcx)
jmp 0xb85c
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0x48, (%rax,%rcx)
movq 0x48(%rsp), %rax
testb $0x1, 0x4(%rax)
je 0xb7d9
movq 0x48(%rsp), %rax
movsbl 0x10(%rax), %eax
cmpl $-0x1, %eax
jne 0xb754
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x9, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xd8, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
jmp 0xb890
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x3f, (%rax,%rcx)
movl 0x38(%rsp), %eax
addl $0xe0, %eax
movb %al, %dl
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, (%rax,%rcx)
movb $0x0, 0x17(%rsp)
movq 0x48(%rsp), %rax
movsbl 0x10(%rax), %eax
cmpl $0x1, %eax
je 0xb7cb
movq 0x48(%rsp), %rax
movsbl 0x10(%rax), %ecx
sarl %ecx
movb %cl, 0x10(%rax)
movb 0x17(%rsp), %al
addb $0x1, %al
movb %al, 0x17(%rsp)
jmp 0xb7a3
movb 0x17(%rsp), %cl
movq 0x48(%rsp), %rax
movb %cl, 0x10(%rax)
jmp 0xb82d
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $0xf, (%rax,%rcx)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
movb $-0x51, (%rax,%rcx)
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
movl 0x28(%rsp), %edx
callq 0xced0
jmp 0xb890
jmp 0xb85c
leaq 0x8c9a(%rip), %rdi      # 0x144d0
movb $0x0, %al
callq 0x10c0
leaq 0x8513(%rip), %rdi      # 0x13d57
leaq 0x8c3f(%rip), %rsi      # 0x1448a
movl $0x436, %edx            # imm = 0x436
leaq 0x8c82(%rip), %rcx      # 0x144d9
callq 0x10e0
movq 0x48(%rsp), %rax
testb $0x1, 0x4(%rax)
je 0xb87c
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
addq $0x8, %rsi
callq 0xbfe0
jmp 0xb88e
movq 0x50(%rsp), %rdi
movl 0x28(%rsp), %esi
movl 0x38(%rsp), %edx
callq 0xced0
jmp 0xb890
movq 0x50(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
callq 0xcfa0
addq $0x58, %rsp
retq
nopl (%rax)