// File: /workspace/github_cpp_makefile_star2_O1/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 0x6b155
movq %rsi, %r15
movq %rdi, %rbx
movl $0x28, %edi
callq 0x40800
movq %rax, %r14
movq %rax, %rdi
callq 0x41310
movq %r14, (%rbx)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x18(%rbx), %rax
cmpq %rax, 0x20(%rbx)
je 0x6b019
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 0x6af66
movq %r13, %rdi
movq 0x37fd6(%rip), %rsi     # 0xa2ef0
movq 0x37fd7(%rip), %rdx     # 0xa2ef8
xorl %ecx, %ecx
callq 0x40b50
testq %rax, %rax
je 0x6af8c
cmpb $0x1, 0x38(%rax)
jne 0x6afba
testb $0x1, 0x28(%rsp)
jne 0x6b1b5
movq %r15, %rdi
callq 0x41310
movq %r12, %rdi
movq %r15, %rsi
callq 0x41bd0
movq %r15, %rdi
callq 0x3fa70
movb $0x1, %al
movq %rax, 0x28(%rsp)
jmp 0x6afd2
movq 0x50(%r14), %rsi
testq %rsi, %rsi
je 0x6b167
movq (%rsi), %rax
movq %r15, %rdi
movq %r12, %rdx
callq *0x18(%rax)
movq %r12, %rdi
movq %r15, %rsi
callq 0x41bd0
jmp 0x6afb0
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 0x41bd0
movq %r15, %rdi
callq 0x3fa70
jmp 0x6afd2
movq %rax, %rdi
movq 0x48(%rsp), %rsi
callq 0x41ad0
movq %r12, %rdi
movq %rax, %rsi
callq 0x410d0
movq 0x38(%rsp), %r13
leaq -0x28(%r13), %rdi
callq 0x420d0
movl %eax, 0x38(%r14)
cmpb $0x0, -0x8(%r13)
jne 0x6aff2
cmpb $0x1, -0x7(%r13)
jne 0x6aff7
orb $0x4, 0x58(%r14)
incq %rbp
movq 0x18(%rbx), %rax
movq 0x20(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rbp, %rcx
ja 0x6af03
movq 0x28(%rsp), %r14
jmp 0x6b01c
xorl %r14d, %r14d
movq 0x10(%rbx), %rdi
testq %rdi, %rdi
je 0x6b20c
movq (%rdi), %rax
leaq 0x30(%rsp), %rsi
callq *0x10(%rax)
movq (%rbx), %rdi
movq 0x10(%rbx), %rsi
addq $0x10, %rsi
callq 0x414a0
movq (%rbx), %rax
movq (%rax), %rdi
movq (%rdi), %rax
callq *0x58(%rax)
testb %al, %al
jne 0x6b263
testb $0x1, %r14b
je 0x6b065
movq (%rbx), %rax
movb $0x1, 0x21(%rax)
movq (%rbx), %rdi
callq 0x420d0
leaq 0x18(%rbx), %rcx
movl %eax, 0x80(%rbx)
leaq 0x50(%rsp), %rsi
movq %rcx, (%rsi)
movaps 0x15faa(%rip), %xmm0    # 0x81030
movups %xmm0, 0x8(%rsi)
movq 0x10(%rbx), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
je 0x6b2b7
movq 0x18(%rbx), %rax
movq 0x20(%rbx), %rcx
subq %rax, %rcx
je 0x6b112
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
movabsq $-0x100000000, %rsi     # imm = 0xFFFFFFFF00000000
movq (%rax,%rdx,8), %rdi
testb $0x2, 0x58(%rdi)
jne 0x6b106
movl 0x34(%rdi), %r9d
testl %r9d, %r9d
js 0x6b10a
movl 0x30(%rdi), %r8d
movl %r9d, %r9d
movq (%rax,%r9,8), %r10
testb $0x4, 0x58(%r10)
jne 0x6b10a
addl 0x38(%r10), %r8d
movl 0x34(%r10), %r9d
addl 0x30(%r10), %r8d
testl %r9d, %r9d
jns 0x6b0ff
movl %r9d, 0x34(%rdi)
movl %r8d, 0x30(%rdi)
testl %r9d, %r9d
jns 0x6b0d8
jmp 0x6b10a
movq %rsi, 0x30(%rdi)
incq %rdx
cmpq %rcx, %rdx
jne 0x6b0c1
movq 0x48(%rbx), %rax
cmpq %rax, 0x50(%rbx)
je 0x6b140
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 0x6b11f
movq %rbx, %rdi
callq 0x41370
movq (%rbx), %r14
leaq 0x30(%rsp), %rdi
callq 0x41cd0
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 0x16405(%rip), %rdx     # 0x81584
movq %rsp, %rdi
movq %r14, %rsi
callq 0x40ef0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r15, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37cef(%rip), %rsi     # 0xa2e90
movq 0x37a90(%rip), %rdx     # 0xa2c38
movq %r15, %rdi
callq 0x41d60
jmp 0x6b309
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x163a0(%rip), %rsi     # 0x81572
leaq 0x163aa(%rip), %rdx     # 0x81583
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37c98(%rip), %rsi     # 0xa2e90
movq 0x37a39(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d60
jmp 0x6b309
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x16372(%rip), %rsi     # 0x8159b
leaq 0x1637b(%rip), %rdx     # 0x815ab
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37c41(%rip), %rsi     # 0xa2e90
movq 0x379e2(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d60
jmp 0x6b309
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x1632c(%rip), %rsi     # 0x815ac
leaq 0x16337(%rip), %rdx     # 0x815be
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37bea(%rip), %rsi     # 0xa2e90
movq 0x3798b(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d60
jmp 0x6b309
movl $0x20, %edi
callq 0x3fb00
movq %rax, %r14
leaq 0x10(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x162eb(%rip), %rsi     # 0x815bf
leaq 0x16305(%rip), %rdx     # 0x815e0
movq %rsp, %rdi
callq 0x3f8a0
movb $0x1, %bpl
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3f890
xorl %ebp, %ebp
movq 0x37b96(%rip), %rsi     # 0xa2e90
movq 0x37937(%rip), %rdx     # 0xa2c38
movq %r14, %rdi
callq 0x41d60
jmp 0x6b32a
jmp 0x6b345
jmp 0x6b32a
jmp 0x6b345
jmp 0x6b32a
jmp 0x6b345
movq %rax, %rbx
movl $0x28, %esi
movq %r14, %rdi
callq 0x40870
jmp 0x6b3b6
movq %rax, %rbx
movq (%rsp), %rdi
cmpq %r15, %rdi
je 0x6b34b
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x40870
jmp 0x6b34b
movq %rax, %rbx
movb $0x1, %bpl
testb %bpl, %bpl
je 0x6b3ac
movq %r14, %rdi
jmp 0x6b385
jmp 0x6b3a9
movq %rax, %rbx
leaq 0x10(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6b37d
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x40870
jmp 0x6b37d
movq %rax, %rbx
movb $0x1, %bpl
testb %bpl, %bpl
je 0x6b3ac
movq %r15, %rdi
callq 0x40080
jmp 0x6b3ac
jmp 0x6b396
jmp 0x6b3a9
jmp 0x6b3a9
jmp 0x6b396
jmp 0x6b3a9
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3fa70
jmp 0x6b3ac
jmp 0x6b3a9
jmp 0x6b3a9
jmp 0x6b3a9
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x41cd0
movq %rbx, %rdi
callq 0x41f00