// File: 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
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6aa90
movq -0x20(%rbp), %rdi
callq 0x6acc0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6ad20
movq %rax, -0x38(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x6acf0
testb $0x1, %al
jne 0x5f7a3
jmp 0x5fac3
leaq -0x28(%rbp), %rdi
callq 0x6ab90
addq $0x8, %rax
movq %rax, -0x40(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6ad50
movq -0x40(%rbp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x5fabe
movq -0x40(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0x5fabe
movq -0x40(%rbp), %rax
movl 0x18(%rax), %eax
movq -0x40(%rbp), %rcx
cmpl 0x14(%rcx), %eax
jne 0x5fabe
movq -0x40(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jge 0x5f806
movq -0x18(%rbp), %rdi
callq 0x52880
movq %rax, -0x48(%rbp)
jmp 0x5f81a
movq -0x18(%rbp), %rdi
movq -0x40(%rbp), %rax
movl 0x18(%rax), %esi
callq 0xaa8d0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x3fd80
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rax
movslq 0x4(%rax), %rsi
callq 0x3fc80
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %eax
movq -0x40(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jl 0x5f91f
movb $0x1, -0x8d(%rbp)
movl $0x20, %edi
callq 0x11250
movq %rax, -0xc8(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x118c0
movq -0xc0(%rbp), %rdx
leaq 0x799aa(%rip), %rsi     # 0xd9232
leaq -0x78(%rbp), %rdi
callq 0x14430
jmp 0x5f893
movq -0xc8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3faa0
jmp 0x5f8a5
movq -0xc8(%rbp), %rdi
movb $0x0, -0x8d(%rbp)
leaq 0xcf896(%rip), %rsi     # 0x12f150
leaq -0x1fdf1(%rip), %rdx    # 0x3fad0
callq 0x11860
jmp 0x5fae4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x5f8fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x11300
leaq -0x79(%rbp), %rdi
callq 0x114d0
testb $0x1, -0x8d(%rbp)
jne 0x5f90e
jmp 0x5f91a
movq -0xc8(%rbp), %rdi
callq 0x11360
jmp 0x5fad8
movq -0x58(%rbp), %rdi
callq 0x3fd40
cmpl $0x1, %eax
jne 0x5f9e4
movb $0x1, -0x8e(%rbp)
movq -0x40(%rbp), %rax
movl $0x0, 0x1c(%rax)
movq -0x58(%rbp), %rdi
callq 0x3f7a0
movq %rax, -0x98(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x5f9cc
movq -0x98(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x50(%rbp), %rdi
movslq -0x9c(%rbp), %rsi
callq 0x3fc80
movq -0xb8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq (%rax), %rdx
movl $0x1, %ecx
callq 0x5f060
testb $0x1, %al
jne 0x5f9b0
jmp 0x5f9b9
movb $0x0, -0x8e(%rbp)
jmp 0x5f9cc
jmp 0x5f9bb
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x5f962
testb $0x1, -0x8e(%rbp)
je 0x5f9e2
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5facb
jmp 0x5f9e4
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rax
movslq (%rax), %rsi
callq 0x3fc80
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x3fd40
cmpl $0x1, %eax
jne 0x5fabc
movb $0x1, -0x9d(%rbp)
movq -0x40(%rbp), %rax
movl $0x1, 0x1c(%rax)
movq -0x58(%rbp), %rdi
xorl %esi, %esi
callq 0x3fce0
movq %rax, -0xa8(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
movl -0xac(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x5faa7
movq -0xa8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x50(%rbp), %rdi
movslq -0xac(%rbp), %rsi
callq 0x3fc80
movq -0xb8(%rbp), %rdi
movq -0xd8(%rbp), %rsi
movq (%rax), %rdx
xorl %ecx, %ecx
callq 0x5f060
testb $0x1, %al
jne 0x5fa8b
jmp 0x5fa94
movb $0x0, -0x9d(%rbp)
jmp 0x5faa7
jmp 0x5fa96
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x5fa40
testb $0x1, -0x9d(%rbp)
je 0x5faba
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5facb
jmp 0x5fabc
jmp 0x5fabe
jmp 0x5f780
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
movq -0x88(%rbp), %rdi
callq 0x118b0
nopw %cs:(%rax,%rax)