// File: /workspace/github_cpp_makefile_star2_O2/jstaursky[P]hutch/src/Sleigh/slgh_compile.cc
// Function: SleighCompile::calcContextVarLayout(int, int, int)
int4 SleighCompile::calcContextVarLayout(int4 start,int4 sz,int4 numbits)

{
  VarnodeSymbol *sym = contexttable[start].sym;
  FieldQuality *qual;
  int4 i,j;
  int4 maxbits;
  
  if ((sym->getSize()) % 4 != 0)
    reportError("Invalid size of context register: "+sym->getName()+" : must be a multiple of 4 bytes",false);
  maxbits = sym->getSize() * 8 -1;
  i = 0;
  while(i<sz) {

    qual = contexttable[i].qual;
    int4 min = qual->low;
    int4 max = qual->high;
    if ((max - min) > (8*sizeof(uintm)))
      reportError("Size of bitfield " + qual->name + " larger than 32-bits",false);
    if (max > maxbits)
      reportError("Scope of bitfield " + qual->name + " extends beyond the size of context register",false);
    j = i+1;
    // Find union of fields overlapping with first field
    while(j<sz) {
      qual = contexttable[j].qual;
      if (qual->low <= max) {	// We have overlap of context variables
	if (qual->high > max)
	  max = qual->high;
	// reportWarning("Local context variables overlap in "+sym->getName(),false);
      }
      else
	break;
      j = j+1;
    }

    int4 alloc = max-min+1;
    int4 startword = numbits / (8*sizeof(uintm));
    int4 endword = (numbits+alloc-1) / (8*sizeof(uintm));
    if (startword != endword)
      numbits = endword * (8*sizeof(uintm)); // Bump up to next word

    uint4 low = numbits;
    numbits += alloc;

    for(;i<j;++i) {
      qual = contexttable[i].qual;
      uint4 l = qual->low - min + low;
      uint4 h = numbits-1-(max-qual->high);
      ContextField *field = new ContextField(qual->signext,l,h);
      addSymbol(new ContextSymbol(qual->name,field,sym,qual->low,qual->high,qual->flow));
    }
    
  }
  sym->markAsContext();
  return numbits;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, 0x20(%rsp)
movl %edx, 0xc(%rsp)
movq %rdi, %r13
movslq %esi, %rax
movq 0x240(%rdi), %rcx
shlq $0x4, %rax
movq (%rcx,%rax), %rbx
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x48(%rax)
testb $0x3, %al
movq %rbx, 0x28(%rsp)
je 0x29efb
leaq 0x8(%rbx), %rdx
leaq 0x2d2d4(%rip), %rsi     # 0x57186
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
callq 0x10cd1
leaq 0x2d2e3(%rip), %rdx     # 0x571a9
leaq 0x68(%rsp), %rdi
movq %rbx, %rsi
callq 0x2eb71
leaq 0x68(%rsp), %rsi
movq %r13, %rdi
xorl %edx, %edx
callq 0x292f0
leaq 0x68(%rsp), %rdi
callq 0xf1a0
leaq 0x38(%rsp), %rdi
callq 0xf1a0
movq 0x28(%rsp), %rbx
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x48(%rax)
shll $0x3, %eax
movl %eax, 0x34(%rsp)
movslq 0xc(%rsp), %r14
xorl %r15d, %r15d
movq %r14, 0x58(%rsp)
cmpl 0xc(%rsp), %r15d
jge 0x2a130
movslq %r15d, %r15
movq 0x240(%r13), %rax
movq %r15, %rdi
shlq $0x4, %rdi
movq 0x8(%rax,%rdi), %rbp
movl 0x20(%rbp), %r8d
movl 0x24(%rbp), %r12d
movl %r12d, %eax
subl %r8d, %eax
cmpl $0x21, %eax
movq %rdi, 0x18(%rsp)
movl %r8d, 0x10(%rsp)
jb 0x29fac
leaq 0x38(%rsp), %rdi
leaq 0x2d268(%rip), %rsi     # 0x571ca
movq %rbp, %rdx
callq 0x10cd1
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
leaq 0x2d25e(%rip), %rdx     # 0x571dc
callq 0x2eb71
movq %r13, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x292f0
movq %rbx, %rdi
callq 0xf1a0
leaq 0x38(%rsp), %rdi
callq 0xf1a0
movq 0x18(%rsp), %rdi
movl 0x10(%rsp), %r8d
cmpl 0x34(%rsp), %r12d
jl 0x2a009
leaq 0x38(%rsp), %rdi
leaq 0x2d232(%rip), %rsi     # 0x571f1
movq %rbp, %rdx
callq 0x10cd1
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
leaq 0x2d229(%rip), %rdx     # 0x57204
callq 0x2eb71
movq %r13, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x292f0
movq %rbx, %rdi
callq 0xf1a0
leaq 0x38(%rsp), %rdi
callq 0xf1a0
movq 0x18(%rsp), %rdi
movl 0x10(%rsp), %r8d
movq 0x240(%r13), %rcx
movq %r15, %r9
shlq $0x20, %r9
leaq 0x1(%r15), %rax
addq %rdi, %rcx
addq $0x18, %rcx
cmpq %r14, %rax
jge 0x2a050
movq (%rcx), %rdx
cmpl %r12d, 0x20(%rdx)
ja 0x2a050
movl 0x24(%rdx), %edx
cmpl %r12d, %edx
cmoval %edx, %r12d
movabsq $0x100000000, %rdx      # imm = 0x100000000
addq %rdx, %r9
incq %rax
addq $0x10, %rcx
jmp 0x2a022
subl %r8d, %r12d
movq 0x20(%rsp), %rcx
leal (%r12,%rcx), %edx
movl %edx, %eax
xorl %ecx, %eax
andl $-0x20, %edx
cmpl $0x20, %eax
cmovbl %ecx, %edx
leal (%rdx,%r12), %eax
incl %eax
movq %rax, 0x20(%rsp)
subl %r8d, %edx
movq %rdx, 0x10(%rsp)
sarq $0x20, %r9
addq $0x8, %rdi
movq %r9, 0x60(%rsp)
cmpq %r9, %r15
jg 0x2a126
movq %r13, %r14
movq 0x240(%r13), %rax
movq %rdi, 0x18(%rsp)
movq (%rax,%rdi), %rbp
movl 0x20(%rbp), %r12d
movq 0x10(%rsp), %rax
addl %eax, %r12d
movl 0x24(%rbp), %r13d
addl %eax, %r13d
pushq $0x28
popq %rdi
callq 0xf370
movq %rax, %rbx
movzbl 0x28(%rbp), %esi
movq %rax, %rdi
movl %r12d, %edx
movl %r13d, %ecx
callq 0x36cd8
pushq $0x50
popq %rdi
callq 0xf370
movq %rax, %r12
movl 0x20(%rbp), %r8d
movl 0x24(%rbp), %r9d
movzbl 0x29(%rbp), %eax
movl %eax, (%rsp)
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
movq 0x28(%rsp), %rcx
callq 0x42654
movq %r14, %r13
movq %r14, %rdi
movq %r12, %rsi
callq 0x29992
incq %r15
movq 0x18(%rsp), %rdi
addq $0x10, %rdi
movq 0x60(%rsp), %r9
jmp 0x2a089
movq 0x58(%rsp), %r14
jmp 0x29f18
movq 0x28(%rsp), %rax
movb $0x1, 0x50(%rax)
movq 0x20(%rsp), %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2a156
jmp 0x2a167
jmp 0x2a156
movq %rax, %r14
leaq 0x68(%rsp), %rdi
callq 0xf1a0
jmp 0x2a16a
jmp 0x2a167
movq %rax, %r14
leaq 0x38(%rsp), %rdi
callq 0xf1a0
jmp 0x2a18f
movq %rax, %r14
pushq $0x28
popq %rsi
movq %rbx, %rdi
jmp 0x2a18a
movq %rax, %r14
pushq $0x50
popq %rsi
movq %r12, %rdi
callq 0xf380
movq %r14, %rdi
callq 0xf6e0
nop