// File: jstaursky[P]hutch/src/Sleigh/slgh_compile.cc
// Function: MacroBuilder::transferOp(OpTpl*, std::vector<HandleTpl*, std::allocator<HandleTpl*>>&)
bool MacroBuilder::transferOp(OpTpl *op,vector<HandleTpl *> &params)

{ // Fix handle details of a macro generated OpTpl relative to its specific invocation
  // and transfer it into the output stream
  VarnodeTpl *outvn = op->getOut();
  int4 handleIndex = 0;
  int4 plus;
  bool hasrealsize = false;
  uintb realsize = 0;

  if (outvn != (VarnodeTpl *)0) {
    plus = outvn->transfer(params);
    if (plus >= 0) {
      reportError("Cannot currently assign to bitrange of macro parameter that is a temporary");
      return false;
    }
  }
  for(int4 i=0;i<op->numInput();++i) {
    VarnodeTpl *vn = op->getIn(i);
    if (vn->getOffset().getType() == ConstTpl::handle) {
      handleIndex = vn->getOffset().getHandleIndex();
      hasrealsize = (vn->getSize().getType() == ConstTpl::real);
      realsize = vn->getSize().getReal();
    }
    plus = vn->transfer(params);
    if (plus >= 0) {
      if (!hasrealsize) {
	reportError("Problem with bit range operator in macro");
	return false;
      }
      uintb newtemp = slgh->getUniqueAddr(); // Generate a new temporary location

      // Generate a SUBPIECE op that implements the offset_plus
      OpTpl *subpieceop = new OpTpl(CPUI_SUBPIECE);
      VarnodeTpl *newvn = new VarnodeTpl(ConstTpl(slgh->getUniqueSpace()),ConstTpl(ConstTpl::real,newtemp),
					 ConstTpl(ConstTpl::real,realsize));
      subpieceop->setOutput(newvn);
      HandleTpl *hand = params[handleIndex];
      VarnodeTpl *origvn = new VarnodeTpl( hand->getSpace(), hand->getPtrOffset(), hand->getSize() );
      subpieceop->addInput(origvn);
      VarnodeTpl *plusvn = new VarnodeTpl( ConstTpl(slgh->getConstantSpace()), ConstTpl(ConstTpl::real,plus),
					   ConstTpl(ConstTpl::real, 4) );
      subpieceop->addInput(plusvn);
      outvec.push_back(subpieceop);

      delete vn;		// Replace original varnode
      op->setInput(new VarnodeTpl( *newvn ), i); // with output of subpiece
    }
  }
  outvec.push_back(op);
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3f7a0
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movb $0x0, -0x31(%rbp)
movq $0x0, -0x40(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x60690
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x4bc50
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jl 0x6068e
leaq -0x61(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x118c0
movq -0x1a8(%rbp), %rdx
leaq 0x78cc2(%rip), %rsi     # 0xd92e7
leaq -0x60(%rbp), %rdi
callq 0x14430
jmp 0x60630
movq -0x1a0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x60370
jmp 0x60642
leaq -0x60(%rbp), %rdi
callq 0x11300
leaq -0x61(%rbp), %rdi
callq 0x114d0
movb $0x0, -0x1(%rbp)
jmp 0x60b84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x60680
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x11300
leaq -0x61(%rbp), %rdi
callq 0x114d0
jmp 0x60b92
jmp 0x60690
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
movl %eax, -0x1ac(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3fcc0
movl %eax, %ecx
movl -0x1ac(%rbp), %eax
cmpl %ecx, %eax
jge 0x60b6c
movq -0x18(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x3fce0
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
callq 0x3fca0
movq %rax, %rdi
callq 0x3fc10
cmpl $0x1, %eax
jne 0x60724
movq -0x80(%rbp), %rdi
callq 0x3fca0
movq %rax, %rdi
callq 0x402b0
movl %eax, -0x2c(%rbp)
movq -0x80(%rbp), %rdi
callq 0x3fbf0
movq %rax, %rdi
callq 0x3fc10
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, -0x31(%rbp)
movq -0x80(%rbp), %rdi
callq 0x3fbf0
movq %rax, %rdi
callq 0x3fc20
movq %rax, -0x40(%rbp)
movq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x4bc50
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jl 0x60b5c
testb $0x1, -0x31(%rbp)
jne 0x607e4
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x118c0
movq -0x1b8(%rbp), %rdx
leaq 0x78bc9(%rip), %rsi     # 0xd9332
leaq -0xa0(%rbp), %rdi
callq 0x14430
jmp 0x60777
movq -0x1a0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x60370
jmp 0x6078c
leaq -0xa0(%rbp), %rdi
callq 0x11300
leaq -0xa1(%rbp), %rdi
callq 0x114d0
movb $0x0, -0x1(%rbp)
jmp 0x60b84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x607d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x11300
leaq -0xa1(%rbp), %rdi
callq 0x114d0
jmp 0x60b92
movq -0x1a0(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x60ba0
movq %rax, -0xb0(%rbp)
movl $0x28, %edi
callq 0x11440
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x1c0(%rbp)
movl $0x3f, %esi
callq 0x3fbb0
jmp 0x6081e
movq -0x1c0(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl $0x68, %edi
callq 0x11440
movq %rax, %rcx
movq -0x1a0(%rbp), %rax
movq %rcx, -0x1d0(%rbp)
movq 0x18(%rax), %rdi
callq 0x48190
movq %rax, -0x1c8(%rbp)
jmp 0x60859
movq -0x1c8(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x49f90
jmp 0x6086e
movq -0xb0(%rbp), %rdx
leaq -0x100(%rbp), %rdi
xorl %esi, %esi
callq 0x49ef0
jmp 0x60885
movq -0x40(%rbp), %rdx
leaq -0x120(%rbp), %rdi
xorl %esi, %esi
callq 0x49ef0
jmp 0x60899
movq -0x1d0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
leaq -0x100(%rbp), %rdx
leaq -0x120(%rbp), %rcx
callq 0x4bac0
jmp 0x608bc
movq -0x1d0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xb8(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0x3fb90
movq -0x20(%rbp), %rdi
movslq -0x2c(%rbp), %rsi
callq 0x6b150
movq (%rax), %rax
movq %rax, -0x128(%rbp)
movl $0x68, %edi
callq 0x11440
movq %rax, -0x1e0(%rbp)
movq -0x128(%rbp), %rdi
callq 0x4e1a0
movq %rax, -0x1d8(%rbp)
jmp 0x6091a
movq -0x128(%rbp), %rdi
callq 0x4e1b0
movq %rax, -0x1e8(%rbp)
jmp 0x6092f
movq -0x128(%rbp), %rdi
callq 0x4e1d0
movq %rax, -0x1f0(%rbp)
jmp 0x60944
movq -0x1f0(%rbp), %rcx
movq -0x1e8(%rbp), %rdx
movq -0x1d8(%rbp), %rsi
movq -0x1e0(%rbp), %rdi
callq 0x4bac0
jmp 0x60967
movq -0x1e0(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0xb8(%rbp), %rdi
movq -0x130(%rbp), %rsi
callq 0x3fa10
movl $0x68, %edi
callq 0x11440
movq %rax, %rcx
movq -0x1a0(%rbp), %rax
movq %rcx, -0x200(%rbp)
movq 0x18(%rax), %rdi
callq 0x48150
movq %rax, -0x1f8(%rbp)
jmp 0x609b5
movq -0x1f8(%rbp), %rsi
leaq -0x158(%rbp), %rdi
callq 0x49f90
jmp 0x609ca
movslq -0x30(%rbp), %rdx
leaq -0x178(%rbp), %rdi
xorl %esi, %esi
callq 0x49ef0
jmp 0x609de
leaq -0x198(%rbp), %rdi
xorl %esi, %esi
movl $0x4, %edx
callq 0x49ef0
jmp 0x609f3
movq -0x200(%rbp), %rdi
leaq -0x158(%rbp), %rsi
leaq -0x178(%rbp), %rdx
leaq -0x198(%rbp), %rcx
callq 0x4bac0
jmp 0x60a16
movq -0x200(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0xb8(%rbp), %rdi
movq -0x138(%rbp), %rsi
callq 0x3fa10
movq -0x1a0(%rbp), %rax
movq 0x28(%rax), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x3f730
movq -0x80(%rbp), %rax
movq %rax, -0x208(%rbp)
cmpq $0x0, %rax
je 0x60a70
movq -0x208(%rbp), %rdi
movl $0x68, %esi
callq 0x11450
movq -0x18(%rbp), %rax
movq %rax, -0x218(%rbp)
movl $0x68, %edi
callq 0x11440
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x210(%rbp)
movq -0xc0(%rbp), %rsi
callq 0x4bb20
jmp 0x60aa0
movq -0x210(%rbp), %rsi
movq -0x218(%rbp), %rdi
movl -0x78(%rbp), %edx
callq 0x4e840
jmp 0x60b5c
movq -0x1c0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
movl $0x28, %esi
callq 0x11450
jmp 0x60b92
movq -0x1d0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
movl $0x68, %esi
callq 0x11450
jmp 0x60b92
movq -0x1e0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
movl $0x68, %esi
callq 0x11450
jmp 0x60b92
movq -0x200(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
movl $0x68, %esi
callq 0x11450
jmp 0x60b92
movq -0x210(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
movl $0x68, %esi
callq 0x11450
jmp 0x60b92
jmp 0x60b5e
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x60697
movq -0x1a0(%rbp), %rax
movq 0x28(%rax), %rdi
leaq -0x18(%rbp), %rsi
callq 0x3f730
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x118b0
nopl (%rax,%rax)