// File: /workspace/github_cpp_makefile_star2_O2/jstaursky[P]hutch/src/Sleigh/slgh_compile.cc
// Function: ConsistencyChecker::findValidRule(Constructor*, std::map<unsigned long, ConsistencyChecker::OptimizeRecord, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, ConsistencyChecker::OptimizeRecord>>>&) const
ConsistencyChecker::OptimizeRecord *ConsistencyChecker::findValidRule(Constructor *ct,map<uintb,OptimizeRecord> &recs) const

{
  map<uintb,OptimizeRecord>::iterator iter;
  iter = recs.begin();
  while(iter != recs.end()) {
    OptimizeRecord &currec( (*iter).second );
    ++iter;
    if ((currec.writecount==1)&&(currec.readcount==1)&&(currec.readsection==currec.writesection)) {
      // Temporary must be read and written exactly once
      ConstructTpl *tpl;
      if (currec.readsection < 0)
	tpl = ct->getTempl();
      else
	tpl = ct->getNamedTempl(currec.readsection);
      const vector<OpTpl *> &ops( tpl->getOpvec() );
      const OpTpl *op = ops[ currec.readop ];
      if (currec.writeop >= currec.readop) // Read must come after write
	throw SleighError("Read of temporary before write");
      if (op->getOpcode() == CPUI_COPY) {
	bool saverecord = true;
	currec.opttype = 0;	// Read op is a COPY
	const VarnodeTpl *vn = op->getOut();
	for(int4 i=currec.writeop+1;i<currec.readop;++i) { // Check for interference between write and read
	  if (readWriteInterference(vn,ops[i],true)) {
	    saverecord = false;
	    break;
	  }
	}
	if (saverecord)
	  return &currec;
      }
      op = ops[ currec.writeop ];
      if (op->getOpcode() == CPUI_COPY) {
	bool saverecord = true;
	currec.opttype = 1;	// Write op is a COPY
	const VarnodeTpl *vn = op->getIn(0);
	for(int4 i=currec.writeop+1;i<currec.readop;++i) { // Check for interference between write and read
	  if (readWriteInterference(vn,ops[i],false)) {
	    saverecord = false;
	    break;
	  }
	}
	if (saverecord)
	  return &currec;
      }
    }
  }
  return (OptimizeRecord *)0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq 0x18(%rdx), %r15
addq $0x8, %rbx
movq %rsi, 0x10(%rsp)
cmpq %rbx, %r15
je 0x28d46
movq %r15, %r12
movq %r15, %rdi
callq 0xf280
movq %rax, %r15
cmpl $0x1, 0x34(%r12)
jne 0x28c39
cmpl $0x1, 0x38(%r12)
jne 0x28c39
movl 0x40(%r12), %esi
cmpl 0x3c(%r12), %esi
jne 0x28c39
testl %esi, %esi
js 0x28c7d
movq %r14, %rdi
callq 0x4443a
movq %rax, %r13
jmp 0x28c81
movq 0x60(%r14), %r13
movslq 0x2c(%r12), %rdx
movl 0x28(%r12), %eax
cmpl %edx, %eax
jge 0x28d57
leaq 0x28(%r12), %rcx
movq %rcx, 0x8(%rsp)
movq 0x8(%r13), %rcx
movq (%rcx,%rdx,8), %rdx
cmpl $0x1, 0x8(%rdx)
jne 0x28cee
andl $0x0, 0x44(%r12)
movslq %eax, %rbp
movq (%rdx), %r14
incq %rbp
movslq 0x2c(%r12), %rax
cmpq %rax, %rbp
jge 0x28d3f
movq 0x8(%r13), %rax
movq (%rax,%rbp,8), %rdx
movq %r14, %rsi
pushq $0x1
popq %rcx
callq 0x28978
incq %rbp
testb %al, %al
je 0x28cba
movq 0x8(%rsp), %rax
movl (%rax), %eax
movq 0x8(%r13), %rcx
movq 0x10(%rsp), %r14
movslq %eax, %rbp
movq (%rcx,%rbp,8), %rax
cmpl $0x1, 0x8(%rax)
jne 0x28c39
movl $0x1, 0x44(%r12)
movq 0x10(%rax), %rax
movq (%rax), %r14
incq %rbp
movslq 0x2c(%r12), %rax
cmpq %rax, %rbp
jge 0x28d3f
movq 0x8(%r13), %rax
movq (%rax,%rbp,8), %rdx
movq %r14, %rsi
xorl %ecx, %ecx
callq 0x28978
incq %rbp
testb %al, %al
je 0x28d12
movq 0x10(%rsp), %r14
jmp 0x28c39
movq 0x8(%rsp), %rax
jmp 0x28d48
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x20
popq %rdi
callq 0xf1d0
movq %rax, %rbx
leaq 0x2e2d1(%rip), %rsi     # 0x5703a
leaq 0x18(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10c3a
movb $0x1, %bpl
leaq 0x18(%rsp), %rsi
movq %rbx, %rdi
callq 0x10d48
xorl %ebp, %ebp
leaq 0x5c67f(%rip), %rsi     # 0x85410
leaq -0x18018(%rip), %rdx    # 0x10d80
movq %rbx, %rdi
callq 0xf690
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0xf1a0
testb %bpl, %bpl
jne 0x28db7
jmp 0x28dbf
movq %rax, %r14
movq %rbx, %rdi
callq 0xf2a0
movq %r14, %rdi
callq 0xf6e0
nop