// File: /workspace/github_c_makefile_star2_O2/mishun[P]plantri/plantri.c
// Function: canon
static int 
canon(int lcolour[], EDGE *can_numberings[][MAXE], int *nbtot, int *nbop)

/* Checks whether the last vertex (number: nv-1) is canonical or not. 
   Returns 1 if yes, 0 if not. One of the criterions a canonical vertex 
   must fulfill is that its colour is minimal.

   IT IS ASSUMED that the values of the colour function are positive
   and at most INT_MAX-MAXN.
 
   A possible starting edge for the construction of a representation is 
   one with lexicographically minimal colour pair (start,INT_MAX-end).
   In can_numberings[][] the canonical numberings are stored as sequences 
   of oriented edges.  For every 0 <= i,j < *nbtot and every 
   0 <= k < ne the edges can_numberings[i][k] and can_numberings[j][k] can 
   be mapped onto each other by an automorphism. The first 
   *nbop numberings are orientation preserving while 
   the rest is orientation reversing.

   In case of only 1 automorphism, in can_numberings[0][0] the "canonical" 
   edge is given.  It is one edge emanating at the canonical vertex. The 
   rest of the numbering is not given. 

   In case of nontrivial automorphisms, can[0] starts with a list of edges 
   adjacent to nv-1. In case of an orientation preserving numbering the deges 
   are listed in ->next direction, otherwise in ->prev direction.

   Works OK if at least one vertex has valence >= 3. Otherwise some numberings 
   are computed twice, since changing the orientation (the cyclic order around 
   each vertex) doesn't change anything */
{
    int i, last_vertex, test;
    int minstart, maxend; /* (minstart,maxend) will be the chosen colour 
                                pair of an edge */
    EDGE *startlist_last[5], *startlist[5*MAXN], *run, *end;
    int list_length_last, list_length;
    int representation[MAXE];
    EDGE *numblist[MAXE], *numblist_mirror[MAXE]; /* lists of edges where 
                        starting gives a canonical representation */
    int numbs = 1, numbs_mirror = 0;
    int colour[MAXN];

    for (i=0; i<nv; i++) colour[i]=lcolour[i]+MAXN;
                               /* to distinguish colours from vertices */
    last_vertex = nv-1;
    minstart = colour[last_vertex];

/* determine the smallest possible end for the vertex "last_vertex" */

    list_length_last = 1; startlist_last[0] = end = firstedge[last_vertex];
    maxend = colour[end->end];

    for (run = end->next; run != end; run = run->next)
      { if (colour[run->end] > maxend)
          { startlist_last[0] = run; 
            list_length_last = 1; maxend = colour[run->end];}
        else if (colour[run->end] == maxend)
          { startlist_last[list_length_last] = run; list_length_last++; }
      }

/* Now we know the pair that SHOULD be minimal and we can determine a list 
   of all edges with this colour pair. If a new pair is found that is even 
   smaller, we can return 0 at once */

    list_length = 0;

    for (i = 0; i < last_vertex; i++) 
      { if (colour[i] < minstart) return 0;
        if (colour[i] == minstart)
          { run = end = firstedge[i];
            do
            {
              if (colour[run->end] > maxend) return 0;
              if (colour[run->end] == maxend)
                { startlist[list_length] = run; list_length++; }
              run = run->next;
            } while (run != end);
          }
      }

/* OK -- so there is no smaller pair and now we have to determine the 
   smallest representation around vertex "last_vertex": */

    testcanon_first_init(startlist_last[0], representation, colour);
    numblist[0] = startlist_last[0];
    test = testcanon_mirror_init(startlist_last[0], representation, colour);
    if (test == 1) 
      { numbs_mirror = 1; numblist_mirror[0] = startlist_last[0]; }
    else if (test == 2)  
      { numbs_mirror = 1; numbs = 0; 
        numblist_mirror[0] = startlist_last[0]; }

    for (i = 1; i < list_length_last; i++)
      { test = testcanon_init(startlist_last[i], representation, colour);
        if (test == 1) { numblist[numbs] = startlist_last[i]; numbs++; }
        else if (test == 2) 
          { numbs_mirror = 0; numbs = 1; numblist[0] = startlist_last[i]; }
            test = testcanon_mirror_init(startlist_last[i], 
                                                     representation, colour);
          if (test == 1)  
            { numblist_mirror[numbs_mirror] = startlist_last[i]; 
              numbs_mirror++; }
          else if (test == 2) 
            { numbs_mirror = 1; numbs = 0; 
              numblist_mirror[0] = startlist_last[i]; }
      }

/* Now we know the best representation we can obtain starting at last_vertex. 
   Now we will check all the others. We can return 0 at once if we find a 
   better one */

    for (i = 0; i < list_length; i++)
      { test = testcanon(startlist[i], representation, colour);
        if (test == 1) { numblist[numbs] = startlist[i]; numbs++; }
        else if (test == 2) return 0;
        test = testcanon_mirror(startlist[i], representation, colour);
        if (test == 1) 
          { numblist_mirror[numbs_mirror] = startlist[i]; numbs_mirror++; }
        else if (test == 2) return 0;
      }

    *nbop = numbs;
    *nbtot = numbs+numbs_mirror;

    if (*nbtot>1)
      { for (i = 0; i < numbs; i++) 
          construct_numb(numblist[i], can_numberings[i]); 
        for (i = 0; i < numbs_mirror; i++, numbs++) 
          construct_numb_mirror(numblist_mirror[i],can_numberings[numbs]);
      }
    else 
      { if (numbs) can_numberings[0][0] = numblist[0];
        else can_numberings[0][0] = numblist_mirror[0]; }

    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2868, %rsp           # imm = 0x2868
movslq 0x23d2fb(%rip), %r9     # 0x242600
xorl %eax, %eax
testl %r9d, %r9d
movl $0x0, %ecx
cmovgl %r9d, %ecx
cmpq %rax, %rcx
je 0x532a
movl (%rdi,%rax,4), %r8d
addl $0x40, %r8d
movl %r8d, 0x50(%rsp,%rax,4)
incq %rax
jmp 0x5313
leaq -0x1(%r9), %rax
movl 0x4c(%rsp,%r9,4), %ecx
leaq 0x206a6(%rip), %r12     # 0x259e0
movq -0x8(%r12,%r9,8), %rdi
movq %rdi, 0x20(%rsp)
movslq 0x4(%rdi), %r8
movl 0x50(%rsp,%r8,4), %r14d
pushq $0x1
popq %r8
movq %rdi, %r9
movq %rdi, %r10
movl %r8d, %r11d
movq 0x18(%r10), %r10
movl %r11d, %r15d
cmpq %rdi, %r10
je 0x5387
movslq 0x4(%r10), %rbx
movl 0x50(%rsp,%rbx,4), %ebx
cmpl %r14d, %ebx
jg 0x537f
jne 0x535a
movq %r10, 0x20(%rsp,%r15,8)
incl %r11d
jmp 0x535a
movq %r10, %r9
movl %ebx, %r14d
jmp 0x5357
movq %r9, 0x20(%rsp)
xorl %edi, %edi
testl %eax, %eax
cmovlel %edi, %eax
xorl %ebx, %ebx
xorl %ebp, %ebp
cmpq %rax, %rdi
je 0x53db
cmpl %ecx, 0x50(%rsp,%rdi,4)
jl 0x5605
jne 0x53d6
movq (%r12,%rdi,8), %r8
movq %r8, %r9
movslq 0x4(%r9), %r10
cmpl %r14d, 0x50(%rsp,%r10,4)
jg 0x5605
jne 0x53cd
movslq %ebx, %rbx
movq %r9, 0x1e60(%rsp,%rbx,8)
incl %ebx
movq 0x18(%r9), %r9
cmpq %r8, %r9
jne 0x53af
incq %rdi
jmp 0x5397
movq %rsi, 0x18(%rsp)
movq %rdx, 0x10(%rsp)
movq 0x20(%rsp), %rbp
leaq 0x150(%rsp), %r12
leaq 0x50(%rsp), %r13
movq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xaccc
movq %rbp, 0x12c0(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xaddf
pushq $0x1
popq %rcx
cmpl $0x2, %eax
je 0x544d
movq $0x0, 0x8(%rsp)
movl %ecx, %r14d
movl %ecx, %r12d
cmpl $0x1, %eax
jne 0x5463
movq %rbp, 0x720(%rsp)
pushq $0x1
popq %r12
movl %r12d, %eax
movq %rax, 0x8(%rsp)
jmp 0x5463
movl %ecx, %r14d
movq %rbp, 0x720(%rsp)
pushq $0x1
popq %rax
movq %rax, 0x8(%rsp)
xorl %r12d, %r12d
pushq $0x1
popq %rbp
cmpq %r15, %rbp
jae 0x5504
movq 0x20(%rsp,%rbp,8), %r13
movq %r13, %rdi
leaq 0x150(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0xaf5b
cmpl $0x2, %eax
je 0x54a3
cmpl $0x1, %eax
jne 0x54b7
movslq %r12d, %r12
movq %r13, 0x12c0(%rsp,%r12,8)
incl %r12d
jmp 0x54b7
movq %r13, 0x12c0(%rsp)
movq $0x0, 0x8(%rsp)
movl %r14d, %r12d
movq %r13, %rdi
leaq 0x150(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0xaddf
cmpl $0x2, %eax
je 0x54e9
cmpl $0x1, %eax
jne 0x54fc
movq 0x8(%rsp), %rax
cltq
movq %r13, 0x720(%rsp,%rax,8)
incl %eax
jmp 0x54f7
movq %r13, 0x720(%rsp)
xorl %r12d, %r12d
movl %r14d, %eax
movq %rax, 0x8(%rsp)
incq %rbp
jmp 0x5466
xorl %r15d, %r15d
testl %ebx, %ebx
cmovlel %r15d, %ebx
xorl %ebp, %ebp
movslq %r12d, %r14
cmpq %r15, %rbx
je 0x5593
movq 0x1e60(%rsp,%r15,8), %r13
movq %r13, %rdi
leaq 0x150(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0xb0d7
cmpl $0x1, %eax
je 0x5543
cmpl $0x2, %eax
jne 0x5551
jmp 0x5605
movq %r13, 0x12c0(%rsp,%r14,8)
incl %r14d
movl %r14d, %r12d
movq %r13, %rdi
leaq 0x150(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0xb20a
cmpl $0x1, %eax
je 0x5575
cmpl $0x2, %eax
jne 0x558b
jmp 0x5605
movq 0x8(%rsp), %rax
cltq
movq %r13, 0x720(%rsp,%rax,8)
incl %eax
movq %rax, 0x8(%rsp)
incq %r15
jmp 0x550f
movq 0x10(%rsp), %rax
movl %r12d, (%rax)
movq 0x8(%rsp), %rax
addl %r12d, %eax
movq 0x18(%rsp), %rcx
movl %eax, (%rcx)
cmpl $0x2, %eax
jl 0x55e1
xorl %r15d, %r15d
testl %r12d, %r12d
cmovlel %r15d, %r12d
leaq 0x20720(%rip), %rbx     # 0x25ce0
cmpq %r15, %r12
je 0x5619
movq 0x12c0(%rsp,%r15,8), %rdi
movq %rbx, %rsi
callq 0xb33d
incq %r15
addq $0xba0, %rbx            # imm = 0xBA0
jmp 0x55c0
testl %r12d, %r12d
leaq 0x720(%rsp), %rax
leaq 0x12c0(%rsp), %rcx
cmoveq %rax, %rcx
movq (%rcx), %rax
movq %rax, 0x206de(%rip)     # 0x25ce0
pushq $0x1
popq %rbp
movl %ebp, %eax
addq $0x2868, %rsp           # imm = 0x2868
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r15d, %r15d
movq 0x8(%rsp), %r12
testl %r12d, %r12d
cmovlel %r15d, %r12d
imulq $0xba0, %r14, %rax      # imm = 0xBA0
leaq 0x206aa(%rip), %rbx     # 0x25ce0
addq %rax, %rbx
pushq $0x1
popq %rbp
cmpq %r15, %r12
je 0x5605
movq 0x720(%rsp,%r15,8), %rdi
movq %rbx, %rsi
callq 0xb476
incq %r15
addq $0xba0, %rbx            # imm = 0xBA0
jmp 0x563c