// File: /workspace/github_c_makefile_star2_O3/lucvoo[P]sparse-dev/cse.c
// Function: cse_collect
void cse_collect(struct instruction *insn)
{
	unsigned long hash;

	hash = (insn->opcode << 3) + (insn->size >> 3);
	switch (insn->opcode) {
	case OP_SEL:
		hash += hashval(insn->src3);
		/* Fall through */	

	/* Binary arithmetic */
	case OP_ADD: case OP_SUB:
	case OP_MUL:
	case OP_DIVU: case OP_DIVS:
	case OP_MODU: case OP_MODS:
	case OP_SHL:
	case OP_LSR: case OP_ASR:
	case OP_AND: case OP_OR:

	/* Binary logical */
	case OP_XOR:

	/* Binary comparison */
	case OP_SET_EQ: case OP_SET_NE:
	case OP_SET_LE: case OP_SET_GE:
	case OP_SET_LT: case OP_SET_GT:
	case OP_SET_B:  case OP_SET_A:
	case OP_SET_BE: case OP_SET_AE:

	/* floating-point arithmetic & comparison */
	case OP_FPCMP ... OP_FPCMP_END:
	case OP_FADD:
	case OP_FSUB:
	case OP_FMUL:
	case OP_FDIV:
		hash += hashval(insn->src2);
		/* Fall through */
	
	/* Unary */
	case OP_NOT: case OP_NEG:
	case OP_FNEG:
	case OP_SYMADDR:
		hash += hashval(insn->src1);
		break;

	case OP_LABEL:
		hash += hashval(insn->bb_true);
		break;

	case OP_SETVAL:
		hash += hashval(insn->val);
		break;

	case OP_SETFVAL:
		hash += hashval(insn->fvalue);
		break;

	case OP_SEXT: case OP_ZEXT:
	case OP_TRUNC:
	case OP_PTRCAST:
	case OP_UTPTR: case OP_PTRTU:
		if (!insn->orig_type || insn->orig_type->bit_size < 0)
			return;
		hash += hashval(insn->src);

		// Note: see corresponding line in insn_compare()
		hash += hashval(insn->orig_type->bit_size);
		break;

	/* Other */
	case OP_PHI: {
		pseudo_t phi;
		FOR_EACH_PTR(insn->phi_list, phi) {
			struct instruction *def;
			if (phi == VOID || !phi->def)
				continue;
			def = phi->def;
			hash += hashval(def->src1);
			hash += hashval(def->bb);
		} END_FOR_EACH_PTR(phi);
		break;
	}

	default:
		/*
		 * Nothing to do, don't even bother hashing them,
		 * we're not going to try to CSE them
		 */
		return;
	}
	hash += hash >> 16;
	hash &= INSN_HASH_SIZE-1;
	add_instruction(insn_hash_table + hash, insn);
}

// Assembly:
pushq %rbp
pushq %rbx
movq %rdi, %rsi
movl (%rdi), %eax
movl %eax, %ecx
andl $0x7f, %ecx
shrl $0xb, %eax
leal (%rax,%rcx,8), %eax
leal -0x8(%rcx), %edx
cmpl $0x29, %edx
jae 0x30dae
addq 0x38(%rsi), %rax
addq 0x30(%rsi), %rax
movl %eax, %ecx
shrl $0x10, %ecx
addl %eax, %ecx
movzbl %cl, %eax
leaq 0x5e95d(%rip), %rcx     # 0x8f700
leaq (%rcx,%rax,8), %rdi
popq %rbx
popq %rbp
jmp 0x227b4
addl $-0x31, %ecx
cmpl $0x18, %ecx
ja 0x30de1
leaq 0x189f7(%rip), %rdx     # 0x497b4
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq 0x40(%rsi), %rcx
testq %rcx, %rcx
je 0x30de1
movl 0x50(%rcx), %ecx
testl %ecx, %ecx
js 0x30de1
addl %eax, %ecx
addq 0x30(%rsi), %rcx
movq %rcx, %rax
jmp 0x30d92
popq %rbx
popq %rbp
retq
movq 0x38(%rsi), %rcx
testq %rcx, %rcx
je 0x30d92
leaq 0x34bdc(%rip), %rdx     # 0x659d0
movq %rcx, %rdi
movzwl (%rdi), %r9d
movsbl %r9b, %r8d
testw %r8w, %r8w
jle 0x30e49
movzwl %r8w, %r8d
movzwl %r9w, %r9d
xorl %r10d, %r10d
cmpl $0x100, %r9d            # imm = 0x100
setae %bl
movq 0x18(%rdi,%r10,8), %r11
testq %r11, %r11
sete %bpl
testb %bpl, %bl
jne 0x30e41
cmpq %rdx, %r11
je 0x30e41
movq 0x18(%r11), %r11
testq %r11, %r11
je 0x30e41
addq 0x30(%r11), %rax
addq 0x8(%r11), %rax
incq %r10
cmpq %r10, %r8
jne 0x30e10
movq 0x10(%rdi), %rdi
cmpq %rcx, %rdi
jne 0x30df7
jmp 0x30d92
addq 0x40(%rsi), %rax
jmp 0x30d8a
addq 0x38(%rsi), %rax
jmp 0x30d92
fldt 0x30(%rsi)
flds 0x1893e(%rip)           # 0x497b0
xorl %ecx, %ecx
fucomi %st(1), %st
setbe %cl
fldz
fcmovbe %st(1), %st
fstp %st(1)
fsubrp %st, %st(1)
fnstcw -0xc(%rsp)
movzwl -0xc(%rsp), %edx
orl $0xc00, %edx            # imm = 0xC00
movw %dx, -0xa(%rsp)
fldcw -0xa(%rsp)
fistpll -0x8(%rsp)
fldcw -0xc(%rsp)
shlq $0x3f, %rcx
xorq -0x8(%rsp), %rcx
addq %rcx, %rax
jmp 0x30d92