// File: jstaursky[P]hutch/src/Sleigh/pcodecompile.cc
// Function: PcodeCompile::buildTruncatedVarnode(VarnodeTpl*, unsigned int, unsigned int)
VarnodeTpl *PcodeCompile::buildTruncatedVarnode(VarnodeTpl *basevn,uint4 bitoffset,uint4 numbits)

{ // Build a truncated form -basevn- that matches the bitrange [ -bitoffset-, -numbits- ] if possible
  // using just ConstTpl mechanics, otherwise return null
  uint4 byteoffset = bitoffset / 8; // Convert to byte units
  uint4 numbytes = numbits / 8;
  uintb fullsz = 0;
  if (basevn->getSize().getType() == ConstTpl::real) {
    // If we know the size of base, make sure the bit range is in bounds
    fullsz = basevn->getSize().getReal();
    if (fullsz == 0) return (VarnodeTpl *)0;
    if (byteoffset + numbytes > fullsz)
      throw SleighError("Requested bit range out of bounds");
  }

  if ((bitoffset % 8) != 0) return (VarnodeTpl *)0;
  if ((numbits % 8) != 0) return (VarnodeTpl *)0;

  if (basevn->getSpace().isUniqueSpace()) // Do we really want to prevent truncated uniques??
    return (VarnodeTpl *)0;

  ConstTpl::const_type offset_type = basevn->getOffset().getType();
  if ((offset_type != ConstTpl::real)&&(offset_type != ConstTpl::handle))
    return (VarnodeTpl *)0;

  ConstTpl specialoff;
  if (offset_type == ConstTpl::handle) {
    // We put in the correct adjustment to offset assuming things are little endian
    // We defer the correct big endian calculation until after the consistency check
    // because we need to know the subtable export sizes
    specialoff = ConstTpl(ConstTpl::handle,basevn->getOffset().getHandleIndex(),
			  ConstTpl::v_offset_plus,byteoffset);
  }
  else { 
    if (basevn->getSize().getType() != ConstTpl::real)
      throw SleighError("Could not construct requested bit range");
    uintb plus;
    if (defaultspace->isBigEndian())
      plus = fullsz - (byteoffset + numbytes);
    else
      plus = byteoffset;
    specialoff = ConstTpl(ConstTpl::real,basevn->getOffset().getReal() + plus);
  }
  VarnodeTpl *res = new VarnodeTpl(basevn->getSpace(),specialoff,ConstTpl(ConstTpl::real,numbytes));
  return res;
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
movl %edx, 0x14c(%rsp)
movl %ecx, 0x148(%rsp)
movq 0x158(%rsp), %rax
movq %rax, 0x38(%rsp)
movl 0x14c(%rsp), %eax
shrl $0x3, %eax
movl %eax, 0x144(%rsp)
movl 0x148(%rsp), %eax
shrl $0x3, %eax
movl %eax, 0x140(%rsp)
movq $0x0, 0x138(%rsp)
movq 0x150(%rsp), %rdi
callq 0xd4930
movq %rax, %rdi
callq 0xde5d0
cmpl $0x0, %eax
jne 0x10fe23
movq 0x150(%rsp), %rdi
callq 0xd4930
movq %rax, %rdi
callq 0xdd890
movq %rax, 0x138(%rsp)
cmpq $0x0, 0x138(%rsp)
jne 0x10fd27
movq $0x0, 0x160(%rsp)
jmp 0x11019b
movl 0x144(%rsp), %eax
addl 0x140(%rsp), %eax
movl %eax, %eax
cmpq 0x138(%rsp), %rax
jbe 0x10fe21
movb $0x1, 0x103(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x28(%rsp)
leaq 0x117(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xe0c80
movq 0x30(%rsp), %rdx
leaq 0x781f0(%rip), %rsi     # 0x187f6a
leaq 0x118(%rsp), %rdi
callq 0xe00a0
jmp 0x10fd89
movq 0x28(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0xd06e0
jmp 0x10fd9d
movq 0x28(%rsp), %rdi
movb $0x0, 0x103(%rsp)
movq 0xb80b7(%rip), %rsi     # 0x1c7e68
movq 0xb7c68(%rip), %rdx     # 0x1c7a20
callq 0xe01f0
jmp 0x1101b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x10fdf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x118(%rsp), %rdi
callq 0xd4550
leaq 0x117(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0x103(%rsp)
jne 0x10fe12
jmp 0x10fe1c
movq 0x28(%rsp), %rdi
callq 0xd5400
jmp 0x1101ab
jmp 0x10fe23
movl 0x14c(%rsp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
je 0x10fe43
movq $0x0, 0x160(%rsp)
jmp 0x11019b
movl 0x148(%rsp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
je 0x10fe63
movq $0x0, 0x160(%rsp)
jmp 0x11019b
movq 0x150(%rsp), %rdi
callq 0xe3000
movq %rax, %rdi
callq 0xd5e30
testb $0x1, %al
jne 0x10fe7e
jmp 0x10fe8f
movq $0x0, 0x160(%rsp)
jmp 0x11019b
movq 0x150(%rsp), %rdi
callq 0xdbaf0
movq %rax, %rdi
callq 0xde5d0
movl %eax, 0xfc(%rsp)
cmpl $0x0, 0xfc(%rsp)
je 0x10fed0
cmpl $0x1, 0xfc(%rsp)
je 0x10fed0
movq $0x0, 0x160(%rsp)
jmp 0x11019b
leaq 0xd8(%rsp), %rdi
callq 0xd4400
cmpl $0x1, 0xfc(%rsp)
jne 0x10ff62
movq 0x150(%rsp), %rdi
callq 0xdbaf0
movq %rax, %rdi
callq 0xd1b90
movl %eax, %edx
movl 0x144(%rsp), %eax
movl %eax, %r8d
leaq 0xb8(%rsp), %rdi
movl $0x1, %esi
movl $0x3, %ecx
callq 0xdea80
movq 0xb8(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0xe8(%rsp)
movl 0xd0(%rsp), %eax
movl %eax, 0xf0(%rsp)
jmp 0x110105
movq 0x150(%rsp), %rdi
callq 0xd4930
movq %rax, %rdi
callq 0xde5d0
cmpl $0x0, %eax
je 0x11005c
movb $0x1, 0x96(%rsp)
movl $0x20, %edi
callq 0xd2b40
movq %rax, 0x18(%rsp)
leaq 0x97(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xe0c80
movq 0x20(%rsp), %rdx
leaq 0x77fd7(%rip), %rsi     # 0x187f8c
leaq 0x98(%rsp), %rdi
callq 0xe00a0
jmp 0x10ffc4
movq 0x18(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0xd06e0
jmp 0x10ffd8
movq 0x18(%rsp), %rdi
movb $0x0, 0x96(%rsp)
movq 0xb7e7c(%rip), %rsi     # 0x1c7e68
movq 0xb7a2d(%rip), %rdx     # 0x1c7a20
callq 0xe01f0
jmp 0x1101b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x110034
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x98(%rsp), %rdi
callq 0xd4550
leaq 0x97(%rsp), %rdi
callq 0xd8ec0
testb $0x1, 0x96(%rsp)
jne 0x11004d
jmp 0x110057
movq 0x18(%rsp), %rdi
callq 0xd5400
jmp 0x1101ab
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0xddec0
testb $0x1, %al
jne 0x110070
jmp 0x110095
movq 0x138(%rsp), %rax
movl 0x144(%rsp), %ecx
addl 0x140(%rsp), %ecx
movl %ecx, %ecx
subq %rcx, %rax
movq %rax, 0x88(%rsp)
jmp 0x1100a4
movl 0x144(%rsp), %eax
movq %rax, 0x88(%rsp)
movq 0x150(%rsp), %rdi
callq 0xdbaf0
movq %rax, %rdi
callq 0xdd890
movq %rax, %rdx
addq 0x88(%rsp), %rdx
leaq 0x68(%rsp), %rdi
xorl %esi, %esi
callq 0xd9880
movq 0x68(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0xe8(%rsp)
movl 0x80(%rsp), %eax
movl %eax, 0xf0(%rsp)
movl $0x68, %edi
callq 0xd8380
movq %rax, 0x8(%rsp)
movq 0x150(%rsp), %rdi
callq 0xe3000
movq %rax, 0x10(%rsp)
jmp 0x110128
movl 0x140(%rsp), %eax
movl %eax, %edx
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
callq 0xd9880
jmp 0x11013f
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
leaq 0x40(%rsp), %rcx
callq 0xdf370
jmp 0x11015d
movq 0x8(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x160(%rsp)
jmp 0x11019b
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
movl $0x68, %esi
callq 0xd8620
jmp 0x1101ab
movq 0x160(%rsp), %rax
addq $0x168, %rsp            # imm = 0x168
retq
movq 0x108(%rsp), %rdi
callq 0xe0be0
nopl (%rax,%rax)