// File: jstaursky[P]hutch/src/Sleigh/translate.cc
// Function: AddrSpaceManager::constructJoinAddress(Translate const*, Address const&, int, Address const&, int)
Address AddrSpaceManager::constructJoinAddress(const Translate *translate,
					       const Address &hiaddr,int4 hisz,
					       const Address &loaddr,int4 losz)
{
  spacetype hitp = hiaddr.getSpace()->getType();
  spacetype lotp = loaddr.getSpace()->getType();
  bool usejoinspace = true;
  if (((hitp != IPTR_SPACEBASE)&&(hitp != IPTR_PROCESSOR))||
      ((lotp != IPTR_SPACEBASE)&&(lotp != IPTR_PROCESSOR)))
    throw LowlevelError("Trying to join in appropriate locations");
  if ((hitp == IPTR_SPACEBASE)||(lotp == IPTR_SPACEBASE)||
      (hiaddr.getSpace() == getDefaultSpace())||
      (loaddr.getSpace() == getDefaultSpace()))
    usejoinspace = false;
  if (hiaddr.isContiguous(hisz,loaddr,losz)) { // If we are contiguous
    if (!usejoinspace) { // and in a mappable space, just return the earliest address
      if (hiaddr.isBigEndian())
	return hiaddr;
      return loaddr;
    }
    else {			// If we are in a non-mappable (register) space, check to see if a parent register exists
      if (hiaddr.isBigEndian()) {
	if (translate->getRegisterName(hiaddr.getSpace(),hiaddr.getOffset(),(hisz+losz)).size() != 0)
	  return hiaddr;
      }
      else {
	if (translate->getRegisterName(loaddr.getSpace(),loaddr.getOffset(),(hisz+losz)).size() != 0)
	  return loaddr;
      }
    }
  }
  // Otherwise construct a formal JoinRecord
  vector<VarnodeData> pieces;
  pieces.push_back(VarnodeData());
  pieces.push_back(VarnodeData());
  pieces[0].space = hiaddr.getSpace();
  pieces[0].offset = hiaddr.getOffset();
  pieces[0].size = hisz;
  pieces[1].space = loaddr.getSpace();
  pieces[1].offset = loaddr.getOffset();
  pieces[1].size = losz;
  JoinRecord *join = findAddJoin(pieces,0);
  return join->getUnified().getAddr();
}

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, 0xc0(%rsp)
movq %rdi, %rax
movq %rax, 0xc8(%rsp)
movl 0x1f0(%rsp), %eax
movq %rdi, 0x1e0(%rsp)
movq %rsi, 0x1d8(%rsp)
movq %rdx, 0x1d0(%rsp)
movq %rcx, 0x1c8(%rsp)
movl %r8d, 0x1c4(%rsp)
movq %r9, 0x1b8(%rsp)
movq 0x1d8(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0x1c8(%rsp), %rdi
callq 0xd9cf0
movq %rax, %rdi
callq 0xcfb80
movl %eax, 0x1b4(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0xd9cf0
movq %rax, %rdi
callq 0xcfb80
movl %eax, 0x1b0(%rsp)
movb $0x1, 0x1af(%rsp)
cmpl $0x2, 0x1b4(%rsp)
je 0xfde15
cmpl $0x1, 0x1b4(%rsp)
jne 0xfde31
cmpl $0x2, 0x1b0(%rsp)
je 0xfdf1f
cmpl $0x1, 0x1b0(%rsp)
je 0xfdf1f
movb $0x1, 0x173(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0xb0(%rsp)
leaq 0x187(%rsp), %rdi
movq %rdi, 0xb8(%rsp)
callq 0xe0c80
movq 0xb8(%rsp), %rdx
leaq 0x89e66(%rip), %rsi     # 0x187cd5
leaq 0x188(%rsp), %rdi
callq 0xe00a0
jmp 0xfde7e
movq 0xb0(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0xd1ae0
jmp 0xfde95
movq 0xb0(%rsp), %rdi
movb $0x0, 0x173(%rsp)
movq 0xc9fe4(%rip), %rsi     # 0x1c7e90
movq 0xc9d1d(%rip), %rdx     # 0x1c7bd0
callq 0xe01f0
jmp 0xfe3a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0xfdef4
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 0xfdf0d
jmp 0xfdf1a
movq 0xb0(%rsp), %rdi
callq 0xd5400
jmp 0xfe396
cmpl $0x2, 0x1b4(%rsp)
je 0xfdf97
cmpl $0x2, 0x1b0(%rsp)
je 0xfdf97
movq 0x1c8(%rsp), %rdi
callq 0xd9cf0
movq 0xd0(%rsp), %rdi
movq %rax, 0xa8(%rsp)
callq 0xd9770
movq %rax, %rcx
movq 0xa8(%rsp), %rax
cmpq %rcx, %rax
je 0xfdf97
movq 0x1b8(%rsp), %rdi
callq 0xd9cf0
movq 0xd0(%rsp), %rdi
movq %rax, 0xa0(%rsp)
callq 0xd9770
movq %rax, %rcx
movq 0xa0(%rsp), %rax
cmpq %rcx, %rax
jne 0xfdf9f
movb $0x0, 0x1af(%rsp)
movq 0x1c8(%rsp), %rdi
movl 0x1c4(%rsp), %esi
movq 0x1b8(%rsp), %rdx
movl 0x1f0(%rsp), %ecx
callq 0xd3ba0
testb $0x1, %al
jne 0xfdfcb
jmp 0xfe18b
testb $0x1, 0x1af(%rsp)
jne 0xfe01c
movq 0x1c8(%rsp), %rdi
callq 0xd8250
testb $0x1, %al
jne 0xfdfe8
jmp 0xfe002
movq 0xc0(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
callq 0xd6c50
jmp 0xfe386
movq 0xc0(%rsp), %rdi
movq 0x1b8(%rsp), %rsi
callq 0xd6c50
jmp 0xfe386
movq 0x1c8(%rsp), %rdi
callq 0xd8250
testb $0x1, %al
jne 0xfe032
jmp 0xfe0e4
movq 0x1d0(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x1c8(%rsp), %rdi
callq 0xd9cf0
movq %rax, 0x90(%rsp)
movq 0x1c8(%rsp), %rdi
callq 0xe03b0
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
movq %rax, %rcx
movl 0x1c4(%rsp), %r8d
addl 0x1f0(%rsp), %r8d
movq (%rsi), %rax
leaq 0x150(%rsp), %rdi
callq *0x40(%rax)
leaq 0x150(%rsp), %rdi
callq 0xd5290
movq %rax, 0x98(%rsp)
leaq 0x150(%rsp), %rdi
callq 0xd4550
movq 0x98(%rsp), %rax
cmpq $0x0, %rax
je 0xfe0df
movq 0xc0(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
callq 0xd6c50
jmp 0xfe386
jmp 0xfe187
movq 0x1d0(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0xd9cf0
movq %rax, 0x78(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0xe03b0
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq %rax, %rcx
movl 0x1c4(%rsp), %r8d
addl 0x1f0(%rsp), %r8d
movq (%rsi), %rax
leaq 0x130(%rsp), %rdi
callq *0x40(%rax)
leaq 0x130(%rsp), %rdi
callq 0xd5290
movq %rax, 0x80(%rsp)
leaq 0x130(%rsp), %rdi
callq 0xd4550
movq 0x80(%rsp), %rax
cmpq $0x0, %rax
je 0xfe185
movq 0xc0(%rsp), %rdi
movq 0x1b8(%rsp), %rsi
callq 0xd6c50
jmp 0xfe386
jmp 0xfe187
jmp 0xfe189
jmp 0xfe18b
leaq 0x118(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0xdc410
movq 0x68(%rsp), %rdi
xorps %xmm0, %xmm0
movaps %xmm0, 0x100(%rsp)
movq $0x0, 0x110(%rsp)
leaq 0x100(%rsp), %rsi
callq 0xde8e0
jmp 0xfe1c8
xorps %xmm0, %xmm0
movaps %xmm0, 0xe0(%rsp)
movq $0x0, 0xf0(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0xde8e0
jmp 0xfe1f6
movq 0x1c8(%rsp), %rdi
callq 0xd9cf0
movq %rax, 0x60(%rsp)
jmp 0xfe20a
xorl %eax, %eax
movl %eax, %esi
leaq 0x118(%rsp), %rdi
callq 0xdbe50
movq 0x60(%rsp), %rcx
movq %rcx, (%rax)
movq 0x1c8(%rsp), %rdi
callq 0xe03b0
movq %rax, 0x58(%rsp)
jmp 0xfe237
xorl %eax, %eax
movl %eax, %esi
movq %rsi, 0x40(%rsp)
leaq 0x118(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0xdbe50
movq 0x58(%rsp), %rcx
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq %rcx, 0x8(%rax)
movl 0x1c4(%rsp), %eax
movl %eax, 0x4c(%rsp)
callq 0xdbe50
movl 0x4c(%rsp), %ecx
movl %ecx, 0x10(%rax)
movq 0x1b8(%rsp), %rdi
callq 0xd9cf0
movq %rax, 0x50(%rsp)
jmp 0xfe290
leaq 0x118(%rsp), %rdi
movl $0x1, %esi
callq 0xdbe50
movq 0x50(%rsp), %rcx
movq %rcx, (%rax)
movq 0x1b8(%rsp), %rdi
callq 0xe03b0
movq %rax, 0x30(%rsp)
jmp 0xfe2be
leaq 0x118(%rsp), %rdi
movq %rdi, 0x20(%rsp)
movl $0x1, %esi
movq %rsi, 0x10(%rsp)
callq 0xdbe50
movq 0x30(%rsp), %rcx
movq 0x10(%rsp), %rsi
movq 0x20(%rsp), %rdi
movq %rcx, 0x8(%rax)
movl 0x1f0(%rsp), %eax
movl %eax, 0x1c(%rsp)
callq 0xdbe50
movl 0x1c(%rsp), %ecx
movq 0xd0(%rsp), %rdi
movq 0x20(%rsp), %rsi
movl %ecx, 0x10(%rax)
xorl %edx, %edx
callq 0xdbc00
movq %rax, 0x28(%rsp)
jmp 0xfe31f
movq 0x28(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rdi
callq 0xd20e0
movq %rax, 0x8(%rsp)
jmp 0xfe340
movq 0x8(%rsp), %rsi
movq 0xc0(%rsp), %rdi
callq 0xd9250
jmp 0xfe354
leaq 0x118(%rsp), %rdi
callq 0xdc1e0
jmp 0xfe386
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x118(%rsp), %rdi
callq 0xdc1e0
jmp 0xfe396
movq 0xc8(%rsp), %rax
addq $0x1e8, %rsp            # imm = 0x1E8
retq
movq 0x178(%rsp), %rdi
callq 0xe0be0
nopw %cs:(%rax,%rax)