// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/simplify.c
// Function: simplify_unop
static int simplify_unop(struct instruction *insn)
{
	struct instruction *def;
	pseudo_t src = insn->src;

	if (constant(src))
		return simplify_constant_unop(insn);

	switch (insn->opcode) {
	case OP_NOT:
		switch (DEF_OPCODE(def, src)) {
		case OP_ADD:
			if (!constant(def->src2))
				break;
			insn->opcode = OP_SUB;	// ~(x + C) --> ~C - x
			src = eval_unop(OP_NOT, insn->size, def->src2);
			use_pseudo(insn, def->src1, &insn->src2);
			return replace_pseudo(insn, &insn->src1, src);
		case OP_NEG:
			insn->opcode = OP_SUB;	// ~(-x) --> x - 1
			insn->src2 = value_pseudo(1);
			return replace_pseudo(insn, &insn->src1, def->src);
		case OP_NOT:			// ~(~x) --> x
			return replace_with_pseudo(insn, def->src);
		case OP_SUB:
			if (!constant(def->src1))
				break;
			insn->opcode = OP_ADD;	// ~(C - x) --> x + ~C
			insn->src2 = eval_unop(OP_NOT, insn->size, def->src1);
			return replace_pseudo(insn, &insn->src1, def->src2);
		case OP_XOR:
			if (!constant(def->src2))
				break;
			insn->opcode = OP_XOR;	// ~(x ^ C) --> x ^ ~C
			insn->src2 = eval_unop(OP_NOT, insn->size, def->src2);
			return replace_pseudo(insn, &insn->src1, def->src1);
		}
		break;
	case OP_NEG:
		switch (DEF_OPCODE(def, src)) {
		case OP_ADD:
			if (!constant(def->src2))
				break;
			insn->opcode = OP_SUB;	// -(x + C) --> (-C - x)
			src = eval_unop(OP_NEG, insn->size, def->src2);
			use_pseudo(insn, def->src1, &insn->src2);
			return replace_pseudo(insn, &insn->src1, src);
		case OP_NEG:			// -(-x) --> x
			return replace_with_pseudo(insn, def->src);
		case OP_NOT:
			insn->opcode = OP_ADD;	// -(~x) --> x + 1
			insn->src2 = value_pseudo(1);
			return replace_pseudo(insn, &insn->src1, def->src);
		case OP_SUB:
			insn->opcode = OP_SUB;		// -(x - y) --> y - x
			use_pseudo(insn, def->src1, &insn->src2);
			return replace_pseudo(insn, &insn->src1, def->src2);
		}
		break;
	default:
		return 0;
	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x382a0
cmpl $0x0, %eax
je 0x35e37
movq -0x10(%rbp), %rdi
callq 0x3b640
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rax
movl (%rax), %eax
andl $0x7f, %eax
movl %eax, -0x24(%rbp)
subl $0x31, %eax
je 0x35e5b
jmp 0x35e4a
movl -0x24(%rbp), %eax
subl $0x32, %eax
je 0x3606a
jmp 0x361f8
movq -0x20(%rbp), %rax
cmpl $0x3, 0x4(%rax)
jne 0x35e85
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
je 0x35e85
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x7f, %eax
movl %eax, -0x28(%rbp)
jmp 0x35e8c
xorl %eax, %eax
movl %eax, -0x28(%rbp)
jmp 0x35e8c
movl -0x28(%rbp), %eax
addl $-0x8, %eax
movl %eax, %ecx
movq %rcx, -0x30(%rbp)
subl $0x2a, %eax
ja 0x36065
movq -0x30(%rbp), %rax
leaq 0x32adc(%rip), %rcx     # 0x68988
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x382a0
cmpl $0x0, %eax
jne 0x35ecc
jmp 0x36065
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0xa, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %esi
shrl $0x8, %esi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
movl $0x31, %edi
callq 0x38da0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rdx
addq $0x30, %rdx
addq $0x8, %rdx
callq 0x381b0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x20(%rbp), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0xa, %ecx
movl %ecx, (%rax)
movl $0x1, %edi
callq 0x1a390
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x357e0
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x382a0
cmpl $0x0, %eax
jne 0x35fa7
jmp 0x36065
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0x8, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %esi
shrl $0x8, %esi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdx
movl $0x31, %edi
callq 0x38da0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x382a0
cmpl $0x0, %eax
jne 0x36010
jmp 0x36065
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0x18, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %esi
shrl $0x8, %esi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
movl $0x31, %edi
callq 0x38da0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
jmp 0x36201
movq -0x20(%rbp), %rax
cmpl $0x3, 0x4(%rax)
jne 0x36094
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
je 0x36094
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x7f, %eax
movl %eax, -0x34(%rbp)
jmp 0x3609b
xorl %eax, %eax
movl %eax, -0x34(%rbp)
jmp 0x3609b
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
subl $0x8, %eax
je 0x360d5
jmp 0x360a8
movl -0x38(%rbp), %eax
subl $0xa, %eax
je 0x361ad
jmp 0x360b6
movl -0x38(%rbp), %eax
subl $0x31, %eax
je 0x3616c
jmp 0x360c4
movl -0x38(%rbp), %eax
subl $0x32, %eax
je 0x36153
jmp 0x361f6
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x382a0
cmpl $0x0, %eax
jne 0x360ec
jmp 0x361f6
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0xa, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %esi
shrl $0x8, %esi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
movl $0x32, %edi
callq 0x38da0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rdx
addq $0x30, %rdx
addq $0x8, %rdx
callq 0x381b0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x20(%rbp), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x357e0
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0x8, %ecx
movl %ecx, (%rax)
movl $0x1, %edi
callq 0x1a390
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
movq -0x10(%rbp), %rax
movl (%rax), %ecx
andl $-0x80, %ecx
orl $0xa, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rdx
addq $0x30, %rdx
addq $0x8, %rdx
callq 0x381b0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x30, %rsi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
callq 0x38d50
movl %eax, -0x4(%rbp)
jmp 0x36208
jmp 0x36201
movl $0x0, -0x4(%rbp)
jmp 0x36208
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)