// File: /workspace/github_c_makefile_star2_O0/mishun[P]plantri/plantri.c
// Function: testcanon
static int 
testcanon(EDGE *givenedge, int representation[], int colour[])

/* Tests whether starting from a given edge and constructing the code in
   "->next" direction, an automorphism or even a better representation 
   can be found. Returns 0 for failure, 1 for an automorphism and 2 for 
   a better representation.  This function exits as soon as a better 
   representation is found. A function that computes and returns the 
   complete better representation can work pretty similar.*/
{
    EDGE *temp, *run;  
    EDGE *startedge[MAXN+1]; /* startedge[i] is the starting edge for 
                        exploring the vertex with the number i+1 */
    int number[MAXN], i;   /* The new numbers of the vertices, starting 
                        at 1 in order to have "0" as a possibility to
                        mark ends of lists and not yet given numbers */
    int last_number, actual_number, vertex;

    for (i = 0; i < nv; i++) number[i] = 0;

    number[givenedge->start] = 1; 
    
    if (givenedge->start != givenedge->end) /* no loop start */
      {
	number[givenedge->end] = 2;
	last_number = 2;
	startedge[1] = givenedge->invers;
      }
    else last_number = 1 ; 

    actual_number = 1;
    temp = givenedge;

/* A representation is a clockwise ordering of all neighbours ended with a 0.
   The neighbours are numbered in the order that they are reached by the BFS 
   procedure. In case a vertex is reached for the first time, not the (new)
   number of the vertex is listed, but its colour. When the list around a
   vertex is finished, it is ended with a 0. Since the colours can be 
   distinguished from the vertices (requirement for the colour function), the
   adjacency list can be reconstructed: Every time a colour is listed, its
   number would be the smallest number not given yet.
   Since the edges when a vertex is reached for the first time are remembered,
   for these edges we in fact have more than just the vertex information -- for
   these edges we also have the exact information which edge occurs in the
   cyclic order. This makes the routine work also for double edges.

   Since every representation starts with the colour of vertex 2, which is
   the same colour all the time, we do not have to store that. 

   In case of a loop as the starting point, the colour of 1 is omitted. 
   Nevertheless also in this case it cannot be mixed up with a non-loop
   starting point, since the number of times a colour occurs is larger
   for loop starters than for non-loop starters.

   Every first entry in a new clockwise ordering (the starting point of the
   edge it was numbered from is determined by the entries before (the first
   time it occurs in the list to be exact), so this is not given either. 
   The K4 could be denoted  c3 c4 0 4 3 0 2 3 0 3 2 0 if ci is the colour
   of vertex i.  Note that the colour of vertex 1 is -- by definition --
   always the smallest one */

    while (last_number < nv)
    {  
        for (run = temp->next; run != temp; run = run->next)
    /* this loop marks all edges around temp->origin. */
          { vertex = run->end;
            if (!number[vertex])
              { startedge[last_number] = run->invers;
                last_number++; number[vertex] = last_number;
                vertex = colour[vertex]; }
            else vertex = number[vertex];
            if (vertex > (*representation)) return 0;
            if (vertex < (*representation)) return 2;
            representation++; 
          }
   /* check whether representation[] is also at the end of a cyclic list */
        if ((*representation) != 0) return 2; 
        representation++;
   /* Next vertex to explore: */
        temp = startedge[actual_number];  actual_number++; 
    }

    while (actual_number <= nv) 
                /* Now we know that all numbers have been given */
    {  
        for (run = temp->next; run != temp; run = run->next)
    /* this loop marks all edges around temp->origin. */
          { 
            vertex = number[run->end];
            if (vertex > (*representation)) return 0;
            if (vertex < (*representation)) return 2;
            representation++;
          }
   /* check whether representation[] is also at the end of a cyclic list */
        if ((*representation) != 0) return 2; 
        representation++;
   /* Next vertex to explore: */
        temp = startedge[actual_number];  actual_number++; 
    }

    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x344(%rbp)
movl -0x344(%rbp), %eax
cmpl 0x24d003(%rip), %eax    # 0x25a620
jge 0xd642
movslq -0x344(%rbp), %rax
movl $0x0, -0x340(%rbp,%rax,4)
movl -0x344(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x344(%rbp)
jmp 0xd611
movq -0x10(%rbp), %rax
movslq (%rax), %rax
movl $0x1, -0x340(%rbp,%rax,4)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x4(%rcx), %eax
je 0xd691
movq -0x10(%rbp), %rax
movslq 0x4(%rax), %rax
movl $0x2, -0x340(%rbp,%rax,4)
movl $0x2, -0x348(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x238(%rbp)
jmp 0xd69b
movl $0x1, -0x348(%rbp)
movl $0x1, -0x34c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movl -0x348(%rbp), %eax
cmpl 0x24cf67(%rip), %eax    # 0x25a620
jge 0xd7f4
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
je 0xd7ac
movq -0x30(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x350(%rbp)
movslq -0x350(%rbp), %rax
cmpl $0x0, -0x340(%rbp,%rax,4)
jne 0xd747
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rcx
movslq -0x348(%rbp), %rax
movq %rcx, -0x240(%rbp,%rax,8)
movl -0x348(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x348(%rbp)
movl -0x348(%rbp), %ecx
movslq -0x350(%rbp), %rax
movl %ecx, -0x340(%rbp,%rax,4)
movq -0x20(%rbp), %rax
movslq -0x350(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x350(%rbp)
jmp 0xd75b
movslq -0x350(%rbp), %rax
movl -0x340(%rbp,%rax,4), %eax
movl %eax, -0x350(%rbp)
movl -0x350(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jle 0xd775
movl $0x0, -0x4(%rbp)
jmp 0xd8c7
movl -0x350(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xd78f
movl $0x2, -0x4(%rbp)
jmp 0xd8c7
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0xd6cb
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xd7c1
movl $0x2, -0x4(%rbp)
jmp 0xd8c7
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
movslq -0x34c(%rbp), %rax
movq -0x240(%rbp,%rax,8), %rax
movq %rax, -0x28(%rbp)
movl -0x34c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34c(%rbp)
jmp 0xd6ad
jmp 0xd7f6
movl -0x34c(%rbp), %eax
cmpl 0x24ce1e(%rip), %eax    # 0x25a620
jg 0xd8c0
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
je 0xd87b
movq -0x30(%rbp), %rax
movslq 0x4(%rax), %rax
movl -0x340(%rbp,%rax,4), %eax
movl %eax, -0x350(%rbp)
movl -0x350(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jle 0xd84a
movl $0x0, -0x4(%rbp)
jmp 0xd8c7
movl -0x350(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xd861
movl $0x2, -0x4(%rbp)
jmp 0xd8c7
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0xd814
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0xd88d
movl $0x2, -0x4(%rbp)
jmp 0xd8c7
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
movslq -0x34c(%rbp), %rax
movq -0x240(%rbp,%rax,8), %rax
movq %rax, -0x28(%rbp)
movl -0x34c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34c(%rbp)
jmp 0xd7f6
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
nopw %cs:(%rax,%rax)