// File: jstaursky[P]hutch/src/Sleigh/translate.cc
// Function: AddrSpaceManager::findAddJoin(std::vector<VarnodeData, std::allocator<VarnodeData>> const&, unsigned int)
JoinRecord *AddrSpaceManager::findAddJoin(const vector<VarnodeData> &pieces,uint4 logicalsize)

{ // Find a pre-existing split record, or create a new one corresponding to the input -pieces-
  // If -logicalsize- is 0, calculate logical size as sum of pieces
  if (pieces.size() == 0)
    throw LowlevelError("Cannot create a join without pieces");
  if ((pieces.size()==1)&&(logicalsize==0))
    throw LowlevelError("Cannot create a single piece join without a logical size");

  uint4 totalsize;
  if (logicalsize != 0) {
    if (pieces.size() != 1)
      throw LowlevelError("Cannot specify logical size for multiple piece join");
    totalsize = logicalsize;
  }
  else {
    totalsize = 0;
    for(int4 i=0;i<pieces.size();++i) // Calculate sum of the sizes of all pieces
      totalsize += pieces[i].size;
    if (totalsize == 0)
      throw LowlevelError("Cannot create a zero size join");
  }

  JoinRecord testnode;

  testnode.pieces = pieces;
  testnode.unified.size = totalsize;
  set<JoinRecord *,JoinRecordCompare>::const_iterator iter;
  iter = splitset.find(&testnode);
  if (iter != splitset.end())		// If already in the set
    return *iter;

  JoinRecord *newjoin = new JoinRecord();
  newjoin->pieces = pieces;
  
  uint4 roundsize = (totalsize + 15) & ~((uint4)0xf);	// Next biggest multiple of 16

  newjoin->unified.space = joinspace;
  newjoin->unified.offset = joinallocate;
  joinallocate += roundsize;
  newjoin->unified.size = totalsize;
  splitset.insert(newjoin);
  splitlist.push_back(newjoin);
  return splitlist.back();
}

// Assembly:
subq $0x1c8, %rsp            # imm = 0x1C8
movq %rdi, 0x1b8(%rsp)
movq %rsi, 0x1b0(%rsp)
movl %edx, 0x1ac(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x1b0(%rsp), %rdi
callq 0xdf340
cmpq $0x0, %rax
jne 0xfd2fe
movb $0x1, 0x173(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x68(%rsp)
leaq 0x187(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0xe0c80
movq 0x70(%rsp), %rdx
leaq 0x8a98c(%rip), %rsi     # 0x187be3
leaq 0x188(%rsp), %rdi
callq 0xe00a0
jmp 0xfd266
movq 0x68(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0xd1ae0
jmp 0xfd27a
movq 0x68(%rsp), %rdi
movb $0x0, 0x173(%rsp)
movq 0xcac02(%rip), %rsi     # 0x1c7e90
movq 0xca93b(%rip), %rdx     # 0x1c7bd0
callq 0xe01f0
jmp 0xfd8e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0xfd2d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xd4550
leaq 0x187(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0x173(%rsp)
jne 0xfd2ef
jmp 0xfd2f9
movq 0x68(%rsp), %rdi
callq 0xd5400
jmp 0xfd8d3
movq 0x1b0(%rsp), %rdi
callq 0xdf340
cmpq $0x1, %rax
jne 0xfd3ff
cmpl $0x0, 0x1ac(%rsp)
jne 0xfd3ff
movb $0x1, 0x14e(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x58(%rsp)
leaq 0x14f(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0xe0c80
movq 0x60(%rsp), %rdx
leaq 0x8a8af(%rip), %rsi     # 0x187c07
leaq 0x150(%rsp), %rdi
callq 0xe00a0
jmp 0xfd367
movq 0x58(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0xd1ae0
jmp 0xfd37b
movq 0x58(%rsp), %rdi
movb $0x0, 0x14e(%rsp)
movq 0xcab01(%rip), %rsi     # 0x1c7e90
movq 0xca83a(%rip), %rdx     # 0x1c7bd0
callq 0xe01f0
jmp 0xfd8e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0xfd3d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x150(%rsp), %rdi
callq 0xd4550
leaq 0x14f(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0x14e(%rsp)
jne 0xfd3f0
jmp 0xfd3fa
movq 0x58(%rsp), %rdi
callq 0xd5400
jmp 0xfd8d3
cmpl $0x0, 0x1ac(%rsp)
je 0xfd513
movq 0x1b0(%rsp), %rdi
callq 0xdf340
cmpq $0x1, %rax
je 0xfd500
movb $0x1, 0x126(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x48(%rsp)
leaq 0x127(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0xe0c80
movq 0x50(%rsp), %rdx
leaq 0x8a7e7(%rip), %rsi     # 0x187c40
leaq 0x128(%rsp), %rdi
callq 0xe00a0
jmp 0xfd468
movq 0x48(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0xd1ae0
jmp 0xfd47c
movq 0x48(%rsp), %rdi
movb $0x0, 0x126(%rsp)
movq 0xcaa00(%rip), %rsi     # 0x1c7e90
movq 0xca739(%rip), %rdx     # 0x1c7bd0
callq 0xe01f0
jmp 0xfd8e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0xfd4d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x128(%rsp), %rdi
callq 0xd4550
leaq 0x127(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0x126(%rsp)
jne 0xfd4f1
jmp 0xfd4fb
movq 0x48(%rsp), %rdi
callq 0xd5400
jmp 0xfd8d3
movl 0x1ac(%rsp), %eax
movl %eax, 0x148(%rsp)
jmp 0xfd675
movl $0x0, 0x148(%rsp)
movl $0x0, 0x120(%rsp)
movslq 0x120(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x1b0(%rsp), %rdi
callq 0xdf340
movq %rax, %rcx
movq 0x40(%rsp), %rax
cmpq %rcx, %rax
jae 0xfd589
movq 0x1b0(%rsp), %rdi
movslq 0x120(%rsp), %rsi
callq 0xd8960
movl 0x10(%rax), %eax
addl 0x148(%rsp), %eax
movl %eax, 0x148(%rsp)
movl 0x120(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x120(%rsp)
jmp 0xfd529
cmpl $0x0, 0x148(%rsp)
jne 0xfd673
movb $0x1, 0xfe(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x30(%rsp)
leaq 0xff(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0xe0c80
movq 0x38(%rsp), %rdx
leaq 0x8a6a8(%rip), %rsi     # 0x187c74
leaq 0x100(%rsp), %rdi
callq 0xe00a0
jmp 0xfd5db
movq 0x30(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0xd1ae0
jmp 0xfd5ef
movq 0x30(%rsp), %rdi
movb $0x0, 0xfe(%rsp)
movq 0xca88d(%rip), %rsi     # 0x1c7e90
movq 0xca5c6(%rip), %rdx     # 0x1c7bd0
callq 0xe01f0
jmp 0xfd8e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0xfd64b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x100(%rsp), %rdi
callq 0xd4550
leaq 0xff(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0xfe(%rsp)
jne 0xfd664
jmp 0xfd66e
movq 0x30(%rsp), %rdi
callq 0xd5400
jmp 0xfd8d3
jmp 0xfd675
leaq 0xc8(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0xce0c0
movq 0x28(%rsp), %rdi
movq 0x1b0(%rsp), %rsi
callq 0xdcdc0
jmp 0xfd69b
movl 0x148(%rsp), %eax
movl %eax, 0xf0(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0xdd4f0
movq 0x78(%rsp), %rdi
addq $0xd8, %rdi
leaq 0xc8(%rsp), %rax
movq %rax, 0xb0(%rsp)
leaq 0xb0(%rsp), %rsi
callq 0xd1350
movq %rax, 0x20(%rsp)
jmp 0xfd6e6
movq 0x78(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0xc0(%rsp)
addq $0xd8, %rdi
callq 0xde7f0
movq %rax, 0xa8(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xcf040
testb $0x1, %al
jne 0xfd737
jmp 0xfd785
leaq 0xc0(%rsp), %rdi
callq 0xd4630
movq (%rax), %rax
movq %rax, 0x1c0(%rsp)
movl $0x1, 0xa4(%rsp)
jmp 0xfd8b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xdaf70
jmp 0xfd8d3
movl $0x30, %edi
callq 0xd8380
movq %rax, 0x18(%rsp)
jmp 0xfd796
movq 0x18(%rsp), %rdi
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rdi)
movaps %xmm0, 0x10(%rdi)
movaps %xmm0, (%rdi)
callq 0xce0c0
movq 0x18(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x1b0(%rsp), %rsi
movq 0x98(%rsp), %rdi
callq 0xdcdc0
jmp 0xfd7d2
movq 0x78(%rsp), %rdi
movl 0x148(%rsp), %eax
addl $0xf, %eax
andl $-0x10, %eax
movl %eax, 0x94(%rsp)
movq 0xb8(%rdi), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0xd0(%rdi), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x20(%rax)
movl 0x94(%rsp), %eax
movl %eax, %ecx
movq 0xd0(%rdi), %rax
addq %rcx, %rax
movq %rax, 0xd0(%rdi)
movl 0x148(%rsp), %ecx
movq 0x98(%rsp), %rax
movl %ecx, 0x28(%rax)
addq $0xd8, %rdi
leaq 0x98(%rsp), %rsi
callq 0xdac50
movb %dl, 0xf(%rsp)
movq %rax, 0x10(%rsp)
jmp 0xfd85c
movq 0x78(%rsp), %rdi
movb 0xf(%rsp), %al
movq 0x10(%rsp), %rcx
movq %rcx, 0x80(%rsp)
movb %al, 0x88(%rsp)
addq $0x108, %rdi            # imm = 0x108
leaq 0x98(%rsp), %rsi
callq 0xd6980
jmp 0xfd88f
movq 0x78(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0xd9350
movq (%rax), %rax
movq %rax, 0x1c0(%rsp)
movl $0x1, 0xa4(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xdaf70
movq 0x1c0(%rsp), %rax
addq $0x1c8, %rsp            # imm = 0x1C8
retq
movq 0x178(%rsp), %rdi
callq 0xe0be0