// File: /workspace/github_cpp_makefile_star2_O3/jstaursky[P]hutch/src/Sleigh/slghsymbol.cc
// Function: Constructor::buildPattern(std::ostream&)
TokenPattern *Constructor::buildPattern(ostream &s)

{
  if (pattern != (TokenPattern *)0) return pattern; // Already built

  pattern = new TokenPattern();
  vector<TokenPattern> oppattern;
  bool recursion = false;
				// Generate pattern for each operand, store in oppattern
  for(int4 i=0;i<operands.size();++i) {
    OperandSymbol *sym = operands[i];
    TripleSymbol *triple = sym->getDefiningSymbol();
    PatternExpression *defexp = sym->getDefiningExpression();
    if (triple != (TripleSymbol *)0) {
      SubtableSymbol *subsym = dynamic_cast<SubtableSymbol *>(triple);
      if (subsym != (SubtableSymbol *)0) {
	if (subsym->isBeingBuilt()) { // Detected recursion
	  if (recursion) {
	    throw SleighError("Illegal recursion");
	  }
				// We should also check that recursion is rightmost extreme
	  recursion = true;
	  oppattern.push_back(TokenPattern());
	}
	else
	  oppattern.push_back(*subsym->buildPattern(s));
      }
      else
	oppattern.push_back(triple->getPatternExpression()->genMinPattern(oppattern));
    }
    else if (defexp != (PatternExpression *)0)
      oppattern.push_back(defexp->genMinPattern(oppattern));
    else {
      throw SleighError(sym->getName()+": operand is undefined");
    }
    TokenPattern &sympat( oppattern.back() );
    sym->minimumlength = sympat.getMinimumLength();
    if (sympat.getLeftEllipsis() || sympat.getRightEllipsis())
      sym->setVariableLength();
  }

  if (pateq == (PatternEquation *)0)
    throw SleighError("Missing equation");

				// Build the entire pattern
  pateq->genPattern(oppattern);
  *pattern = pateq->getTokenPattern();
  if (pattern->alwaysFalse())
    throw SleighError("Impossible pattern");
  if (recursion)
    pattern->setRightEllipsis(true);
  minimumlength = pattern->getMinimumLength(); // Get length of the pattern in bytes

				// Resolve offsets of the operands
  OperandResolve resolve(operands);
  if (!pateq->resolveOperandLeft(resolve))
    throw SleighError("Unable to resolve operand offsets");

  for(int4 i=0;i<operands.size();++i) { // Unravel relative offsets to absolute (if possible)
    int4 base,offset;
    OperandSymbol *sym = operands[i];
    if (sym->isOffsetIrrelevant()) {
      sym->offsetbase = -1;
      sym->reloffset = 0;
      continue;
    }
    base = sym->offsetbase;
    offset = sym->reloffset;
    while(base >= 0) {
      sym = operands[base];
      if (sym->isVariableLength()) break; // Cannot resolve to absolute
      base = sym->offsetbase;
      offset += sym->getMinimumLength();
      offset += sym->reloffset;
      if (base < 0) {
	operands[i]->offsetbase = base;
	operands[i]->reloffset = offset;
      }
    }
  }

  // Make sure context expressions are valid
  for(int4 i=0;i<context.size();++i)
    context[i]->validate();

  orderOperands();		// Order the operands based on offset dependency
  return pattern;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq (%rdi), %r14
testq %r14, %r14
jne 0x6ae72
movq %rsi, %r15
movq %rdi, %rbx
movl $0x28, %edi
callq 0x40810
movq %rax, %r14
movq %rax, %rdi
callq 0x41320
movq %r14, (%rbx)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x18(%rbx), %rax
cmpq %rax, 0x20(%rbx)
je 0x6ad45
movq %r15, 0x48(%rsp)
xorl %ebp, %ebp
movq %rsp, %r15
leaq 0x30(%rsp), %r12
movq $0x0, 0x28(%rsp)
movq (%rax,%rbp,8), %r14
movq 0x48(%r14), %r13
testq %r13, %r13
je 0x6ac92
movq %r13, %rdi
movq 0x382aa(%rip), %rsi     # 0xa2ef0
movq 0x382ab(%rip), %rdx     # 0xa2ef8
xorl %ecx, %ecx
callq 0x40b60
testq %rax, %rax
je 0x6acb8
cmpb $0x1, 0x38(%rax)
jne 0x6ace6
testb $0x1, 0x28(%rsp)
jne 0x6aed2
movq %r15, %rdi
callq 0x41320
movq %r12, %rdi
movq %r15, %rsi
callq 0x41be0
movq %r15, %rdi
callq 0x3fa70
movb $0x1, %al
movq %rax, 0x28(%rsp)
jmp 0x6acfe
movq 0x50(%r14), %rsi
testq %rsi, %rsi
je 0x6ae84
movq (%rsi), %rax
movq %r15, %rdi
movq %r12, %rdx
callq *0x18(%rax)
movq %r12, %rdi
movq %r15, %rsi
callq 0x41be0
jmp 0x6acdc
movq (%r13), %rax
movq %r13, %rdi
callq *0x38(%rax)
movq (%rax), %rcx
movq %r15, %rdi
movq %rax, %rsi
movq %r12, %rdx
callq *0x18(%rcx)
movq %r12, %rdi
movq %r15, %rsi
callq 0x41be0
movq %r15, %rdi
callq 0x3fa70
jmp 0x6acfe
movq %rax, %rdi
movq 0x48(%rsp), %rsi
callq 0x41ae0
movq %r12, %rdi
movq %rax, %rsi
callq 0x410e0
movq 0x38(%rsp), %r13
leaq -0x28(%r13), %rdi
callq 0x420e0
movl %eax, 0x38(%r14)
cmpb $0x0, -0x8(%r13)
jne 0x6ad1e
cmpb $0x1, -0x7(%r13)
jne 0x6ad23
orb $0x4, 0x58(%r14)
incq %rbp
movq 0x18(%rbx), %rax
movq 0x20(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rbp, %rcx
ja 0x6ac2f
movq 0x28(%rsp), %r14
jmp 0x6ad48
xorl %r14d, %r14d
movq 0x10(%rbx), %rdi
testq %rdi, %rdi
je 0x6af29
movq (%rdi), %rax
leaq 0x30(%rsp), %rsi
callq *0x10(%rax)
movq (%rbx), %rdi
movq 0x10(%rbx), %rsi
addq $0x10, %rsi
callq 0x414b0
movq (%rbx), %rax
movq (%rax), %rdi
movq (%rdi), %rax
callq *0x58(%rax)
testb %al, %al
jne 0x6af80
movq (%rbx), %rdi
testb $0x1, %r14b
je 0x6ad91
movb $0x1, 0x21(%rdi)
callq 0x420e0
leaq 0x18(%rbx), %rcx
movl %eax, 0x80(%rbx)
leaq 0x50(%rsp), %rsi
movq %rcx, (%rsi)
movaps 0x16281(%rip), %xmm0    # 0x81030
movups %xmm0, 0x8(%rsi)
movq 0x10(%rbx), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
je 0x6afd4
movq 0x18(%rbx), %rax
movq 0x20(%rbx), %rcx
subq %rax, %rcx
je 0x6ae2f
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
movq (%rax,%rdx,8), %rsi
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
testb $0x2, 0x58(%rsi)
movl $0x0, %edi
jne 0x6ae20
movl 0x34(%rsi), %r8d
testl %r8d, %r8d
js 0x6ae27
movl 0x30(%rsi), %edi
movl %r8d, %r8d
movq (%rax,%r8,8), %r9
testb $0x4, 0x58(%r9)
jne 0x6ae27
addl 0x38(%r9), %edi
movl 0x34(%r9), %r8d
addl 0x30(%r9), %edi
testl %r8d, %r8d
jns 0x6ae01
movl %r8d, 0x34(%rsi)
movl %edi, 0x30(%rsi)
incq %rdx
cmpq %rcx, %rdx
jne 0x6ade0
movq 0x48(%rbx), %rax
cmpq %rax, 0x50(%rbx)
je 0x6ae5d
xorl %r14d, %r14d
movq (%rax,%r14,8), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
incq %r14
movq 0x48(%rbx), %rax
movq 0x50(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r14, %rcx
ja 0x6ae3c
movq %rbx, %rdi
callq 0x41380
movq (%rbx), %r14
leaq 0x30(%rsp), %rdi
callq 0x41ce0
movq %r14, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r15
addq $0x8, %r14
leaq 0x166e8(%rip), %rdx     # 0x81584
movq %rsp, %rdi
movq %r14, %rsi
callq 0x40f00
movb $0x1, %bpl
movq %rsp, %rsi
movq %r15, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37fd2(%rip), %rsi     # 0xa2e90
movq 0x37d73(%rip), %rdx     # 0xa2c38
movq %r15, %rdi
callq 0x41d70
jmp 0x6b026
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x16683(%rip), %rsi     # 0x81572
leaq 0x1668d(%rip), %rdx     # 0x81583
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37f7b(%rip), %rsi     # 0xa2e90
movq 0x37d1c(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d70
jmp 0x6b026
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x16655(%rip), %rsi     # 0x8159b
leaq 0x1665e(%rip), %rdx     # 0x815ab
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37f24(%rip), %rsi     # 0xa2e90
movq 0x37cc5(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d70
jmp 0x6b026
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x1660f(%rip), %rsi     # 0x815ac
leaq 0x1661a(%rip), %rdx     # 0x815be
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37ecd(%rip), %rsi     # 0xa2e90
movq 0x37c6e(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d70
jmp 0x6b026
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x165ce(%rip), %rsi     # 0x815bf
leaq 0x165e8(%rip), %rdx     # 0x815e0
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37e79(%rip), %rsi     # 0xa2e90
movq 0x37c1a(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d70
jmp 0x6b047
jmp 0x6b067
jmp 0x6b047
jmp 0x6b067
jmp 0x6b047
jmp 0x6b067
movq %rax, %rbx
movl $0x28, %esi
movq %r14, %rdi
callq 0x40880
jmp 0x6b0cd
movq %rax, %rbx
movq (%rsp), %rdi
cmpq %r15, %rdi
je 0x6b060
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x40880
testb %bpl, %bpl
jne 0x6b06a
jmp 0x6b0c3
movq %rax, %rbx
movq %r14, %rdi
jmp 0x6b09c
jmp 0x6b0c0
movq %rax, %rbx
leaq 0x10(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6b08f
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x40880
testb %bpl, %bpl
jne 0x6b099
jmp 0x6b0c3
movq %rax, %rbx
movq %r15, %rdi
callq 0x40090
jmp 0x6b0c3
jmp 0x6b0ad
jmp 0x6b0c0
jmp 0x6b0c0
jmp 0x6b0ad
jmp 0x6b0c0
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3fa70
jmp 0x6b0c3
jmp 0x6b0c0
jmp 0x6b0c0
jmp 0x6b0c0
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x41ce0
movq %rbx, %rdi
callq 0x41f10
nop