// File: /workspace/github_c_makefile_star2_O0/YanjieZe[P]CacheLab/test-trans.c
// Function: eval_perf
void eval_perf(unsigned int s, unsigned int E, unsigned int b)
{
    int i,flag;
    unsigned int len, hits, misses, evictions;
    unsigned long long int marker_start, marker_end, addr;
    char buf[1000], cmd[255];
    char filename[128];

    registerFunctions(); 

    /* Open the complete trace file */
    FILE* full_trace_fp;  
    FILE* part_trace_fp; 

    /* Evaluate the performance of each registered transpose function */

    for (i=0; i<func_counter; i++) {
        if (strcmp(func_list[i].description, SUBMIT_DESCRIPTION) == 0 )
            results.funcid = i; /* remember which function is the submission */


        printf("\nFunction %d (%d total)\nStep 1: Validating and generating memory traces\n",i,func_counter);
        /* Use valgrind to generate the trace */

        sprintf(cmd, "valgrind --tool=lackey --trace-mem=yes --log-fd=1 -v ./tracegen -M %d -N %d -F %d  > trace.tmp", M, N,i);
        flag=WEXITSTATUS(system(cmd));
        if (0!=flag) {
            printf("Validation error at function %d! Run ./tracegen -M %d -N %d -F %d for details.\nSkipping performance evaluation for this function.\n",flag-1,M,N,i);      
            continue;
        }

        /* Get the start and end marker addresses */
        FILE* marker_fp = fopen(".marker", "r");
        assert(marker_fp);
        fscanf(marker_fp, "%llx %llx", &marker_start, &marker_end);
        fclose(marker_fp);


        func_list[i].correct=1;

        /* Save the correctness of the transpose submission */
        if (results.funcid == i ) {
            results.correct = 1;
        }

        full_trace_fp = fopen("trace.tmp", "r");
        assert(full_trace_fp);


        /* Filtered trace for each transpose function goes in a separate file */
        sprintf(filename, "trace.f%d", i);
        part_trace_fp = fopen(filename, "w");
        assert(part_trace_fp);
    
        /* Locate trace corresponding to the trans function */
        flag = 0;
        while (fgets(buf, 1000, full_trace_fp) != NULL) {

            /* We are only interested in memory access instructions */
            if (buf[0]==' ' && buf[2]==' ' &&
                (buf[1]=='S' || buf[1]=='M' || buf[1]=='L' )) {
                sscanf(buf+3, "%llx,%u", &addr, &len);
        
                /* If start marker found, set flag */
                if (addr == marker_start)
                    flag = 1;

                /* Valgrind creates many spurious accesses to the
                   stack that have nothing to do with the students
                   code. At the moment, we are ignoring all stack
                   accesses by using the simple filter of recording
                   accesses to only the low 32-bit portion of the
                   address space. At some point it would be nice to
                   try to do more informed filtering so that would
                   eliminate the valgrind stack references while
                   include the student stack references. */
                if (flag && addr < 0xffffffff) {
                    fputs(buf, part_trace_fp);
                }

                /* if end marker found, close trace file */
                if (addr == marker_end) {
                    flag = 0;
                    fclose(part_trace_fp);
                    break;
                }
            }
        }
        fclose(full_trace_fp);

        /* Run the reference simulator */
        printf("Step 2: Evaluating performance (s=%d, E=%d, b=%d)\n", s, E, b);
        char cmd[255];
        sprintf(cmd, "./csim-ref -s %u -E %u -b %u -t trace.f%d > /dev/null", 
                s, E, b, i);
        system(cmd);
    
        /* Collect results from the reference simulator */
        FILE* in_fp = fopen(".csim_results","r");
        assert(in_fp);
        fscanf(in_fp, "%u %u %u", &hits, &misses, &evictions);
        fclose(in_fp);
        func_list[i].num_hits = hits;
        func_list[i].num_misses = misses;
        func_list[i].num_evictions = evictions;
        printf("func %u (%s): hits:%u, misses:%u, evictions:%u\n",
               i, func_list[i].description, hits, misses, evictions);
    
        /* If it is transpose_submit(), record number of misses */
        if (results.funcid == i) {
            results.misses = misses;
        }
    }
  
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6e0, %rsp            # imm = 0x6E0
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl %edx, -0xc(%rbp)
movb $0x0, %al
callq 0x5c2a
movl $0x0, -0x10(%rbp)
movl -0x10(%rbp), %eax
leaq 0x70f4(%rip), %rcx      # 0x83a0
cmpl (%rcx), %eax
jge 0x16f0
movslq -0x10(%rbp), %rcx
leaq 0x70f1(%rip), %rax      # 0x83b0
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
leaq 0x4d33(%rip), %rsi      # 0x6004
callq 0x10c0
cmpl $0x0, %eax
jne 0x12e4
movl -0x10(%rbp), %eax
movl %eax, 0x6dec(%rip)      # 0x80d0
movl -0x10(%rbp), %esi
leaq 0x70b2(%rip), %rax      # 0x83a0
movl (%rax), %edx
leaq 0x4d22(%rip), %rdi      # 0x6019
movb $0x0, %al
callq 0x1060
leaq -0x530(%rbp), %rdi
movl 0x7089(%rip), %edx      # 0x8394
movl 0x7087(%rip), %ecx      # 0x8398
movl -0x10(%rbp), %r8d
leaq 0x4d46(%rip), %rsi      # 0x6062
movb $0x0, %al
callq 0x1150
leaq -0x530(%rbp), %rdi
callq 0x1050
andl $0xff00, %eax           # imm = 0xFF00
sarl $0x8, %eax
movl %eax, -0x14(%rbp)
xorl %eax, %eax
cmpl -0x14(%rbp), %eax
je 0x136a
movl -0x14(%rbp), %esi
subl $0x1, %esi
movl 0x7047(%rip), %edx      # 0x8394
movl 0x7045(%rip), %ecx      # 0x8398
movl -0x10(%rbp), %r8d
leaq 0x4d63(%rip), %rdi      # 0x60c1
movb $0x0, %al
callq 0x1060
jmp 0x16e2
leaq 0x4dd3(%rip), %rdi      # 0x6144
leaq 0x4dd2(%rip), %rsi      # 0x614a
callq 0x1120
movq %rax, -0x5c8(%rbp)
cmpq $0x0, -0x5c8(%rbp)
je 0x1390
jmp 0x13af
leaq 0x4db5(%rip), %rdi      # 0x614c
leaq 0x4db8(%rip), %rsi      # 0x6156
movl $0x50, %edx
leaq 0x4db9(%rip), %rcx      # 0x6163
callq 0x1070
movq -0x5c8(%rbp), %rdi
leaq 0x4ddf(%rip), %rsi      # 0x619c
leaq -0x30(%rbp), %rdx
leaq -0x38(%rbp), %rcx
movb $0x0, %al
callq 0x1030
movq -0x5c8(%rbp), %rdi
callq 0x1040
movslq -0x10(%rbp), %rcx
leaq 0x6fcd(%rip), %rax      # 0x83b0
shlq $0x5, %rcx
addq %rcx, %rax
movb $0x1, 0x10(%rax)
movl 0x6cdc(%rip), %eax      # 0x80d0
cmpl -0x10(%rbp), %eax
jne 0x1403
movl $0x1, 0x6cd1(%rip)      # 0x80d4
leaq 0x4cad(%rip), %rdi      # 0x60b7
leaq 0x4d39(%rip), %rsi      # 0x614a
callq 0x1120
movq %rax, -0x5b8(%rbp)
cmpq $0x0, -0x5b8(%rbp)
je 0x1429
jmp 0x1448
leaq 0x4d76(%rip), %rdi      # 0x61a6
leaq 0x4d1f(%rip), %rsi      # 0x6156
movl $0x5d, %edx
leaq 0x4d20(%rip), %rcx      # 0x6163
callq 0x1070
leaq -0x5b0(%rbp), %rdi
movl -0x10(%rbp), %edx
leaq 0x4d5b(%rip), %rsi      # 0x61b4
movb $0x0, %al
callq 0x1150
leaq -0x5b0(%rbp), %rdi
leaq 0x4d50(%rip), %rsi      # 0x61be
callq 0x1120
movq %rax, -0x5c0(%rbp)
cmpq $0x0, -0x5c0(%rbp)
je 0x1486
jmp 0x14a5
leaq 0x4d33(%rip), %rdi      # 0x61c0
leaq 0x4cc2(%rip), %rsi      # 0x6156
movl $0x63, %edx
leaq 0x4cc3(%rip), %rcx      # 0x6163
callq 0x1070
movl $0x0, -0x14(%rbp)
leaq -0x430(%rbp), %rdi
movq -0x5b8(%rbp), %rdx
movl $0x3e8, %esi            # imm = 0x3E8
callq 0x10b0
cmpq $0x0, %rax
je 0x158e
movsbl -0x430(%rbp), %eax
cmpl $0x20, %eax
jne 0x1589
movsbl -0x42e(%rbp), %eax
cmpl $0x20, %eax
jne 0x1589
movsbl -0x42f(%rbp), %eax
cmpl $0x53, %eax
je 0x1512
movsbl -0x42f(%rbp), %eax
cmpl $0x4d, %eax
je 0x1512
movsbl -0x42f(%rbp), %eax
cmpl $0x4c, %eax
jne 0x1589
leaq -0x430(%rbp), %rdi
addq $0x3, %rdi
leaq 0x4caa(%rip), %rsi      # 0x61ce
leaq -0x40(%rbp), %rdx
leaq -0x18(%rbp), %rcx
movb $0x0, %al
callq 0x1110
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0x1544
movl $0x1, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1568
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, -0x40(%rbp)
jae 0x1568
leaq -0x430(%rbp), %rdi
movq -0x5c0(%rbp), %rsi
callq 0x1080
movq -0x40(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x1587
movl $0x0, -0x14(%rbp)
movq -0x5c0(%rbp), %rdi
callq 0x1040
jmp 0x158e
jmp 0x1589
jmp 0x14ac
movq -0x5b8(%rbp), %rdi
callq 0x1040
movl -0x4(%rbp), %esi
movl -0x8(%rbp), %edx
movl -0xc(%rbp), %ecx
leaq 0x4c2c(%rip), %rdi      # 0x61d6
movb $0x0, %al
callq 0x1060
leaq -0x6d0(%rbp), %rdi
movl -0x4(%rbp), %edx
movl -0x8(%rbp), %ecx
movl -0xc(%rbp), %r8d
movl -0x10(%rbp), %r9d
leaq 0x4c3c(%rip), %rsi      # 0x6209
movb $0x0, %al
callq 0x1150
leaq -0x6d0(%rbp), %rdi
callq 0x1050
leaq 0x4c58(%rip), %rdi      # 0x623f
leaq 0x4b5c(%rip), %rsi      # 0x614a
callq 0x1120
movq %rax, -0x6d8(%rbp)
cmpq $0x0, -0x6d8(%rbp)
je 0x1606
jmp 0x1625
leaq 0x4c40(%rip), %rdi      # 0x624d
leaq 0x4b42(%rip), %rsi      # 0x6156
movl $0x92, %edx
leaq 0x4b43(%rip), %rcx      # 0x6163
callq 0x1070
movq -0x6d8(%rbp), %rdi
leaq 0x4c20(%rip), %rsi      # 0x6253
leaq -0x1c(%rbp), %rdx
leaq -0x20(%rbp), %rcx
leaq -0x24(%rbp), %r8
movb $0x0, %al
callq 0x1030
movq -0x6d8(%rbp), %rdi
callq 0x1040
movl -0x1c(%rbp), %ecx
movslq -0x10(%rbp), %rdx
leaq 0x6d50(%rip), %rax      # 0x83b0
shlq $0x5, %rdx
addq %rdx, %rax
movl %ecx, 0x14(%rax)
movl -0x20(%rbp), %ecx
movslq -0x10(%rbp), %rdx
leaq 0x6d38(%rip), %rax      # 0x83b0
shlq $0x5, %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movl -0x24(%rbp), %ecx
movslq -0x10(%rbp), %rdx
leaq 0x6d20(%rip), %rax      # 0x83b0
shlq $0x5, %rdx
addq %rdx, %rax
movl %ecx, 0x1c(%rax)
movl -0x10(%rbp), %esi
movslq -0x10(%rbp), %rcx
leaq 0x6d08(%rip), %rax      # 0x83b0
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdx
movl -0x1c(%rbp), %ecx
movl -0x20(%rbp), %r8d
movl -0x24(%rbp), %r9d
leaq 0x4b97(%rip), %rdi      # 0x625c
movb $0x0, %al
callq 0x1060
movl 0x69fe(%rip), %eax      # 0x80d0
cmpl -0x10(%rbp), %eax
jne 0x16e0
movl -0x20(%rbp), %eax
movl %eax, 0x69f8(%rip)      # 0x80d8
jmp 0x16e2
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x12a2
addq $0x6e0, %rsp            # imm = 0x6E0
popq %rbp
retq
nopl (%rax)