// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x6b8, %rsp            # imm = 0x6B8
movl %edx, 0x14(%rsp)
movl %esi, 0x10(%rsp)
movl %edi, 0xc(%rsp)
xorl %eax, %eax
callq 0x5a1f
leaq 0x70a9(%rip), %r15      # 0x83c0
movl (%r15), %ebx
testl %ebx, %ebx
jle 0x1642
leaq 0x70a7(%rip), %rbp      # 0x83d0
leaq 0xc0(%rsp), %r12
xorl %r13d, %r13d
movq %r13, %r14
shlq $0x5, %r14
movq 0x8(%rbp,%r14), %rdi
leaq 0x4cbd(%rip), %rsi      # 0x6004
callq 0x10d0
testl %eax, %eax
jne 0x1357
movl %r13d, 0x6d99(%rip)     # 0x80f0
leaq 0x4cbb(%rip), %rdi      # 0x6019
movl %r13d, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x1070
movl 0x7048(%rip), %edx      # 0x83b8
movl 0x7046(%rip), %ecx      # 0x83bc
leaq 0x5b0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x4cda(%rip), %rsi      # 0x6062
movl %r13d, %r8d
xorl %eax, %eax
callq 0x1160
movq %rbx, %rdi
callq 0x1060
shrl $0x8, %eax
andl $0xff, %eax
je 0x13ca
decl %eax
movl 0x700c(%rip), %edx      # 0x83b8
movl 0x700a(%rip), %ecx      # 0x83bc
leaq 0x4d08(%rip), %rdi      # 0x60c1
movl %eax, %esi
movl %r13d, %r8d
xorl %eax, %eax
callq 0x1070
jmp 0x1633
leaq 0x4d73(%rip), %rdi      # 0x6144
leaq 0x4d72(%rip), %rsi      # 0x614a
callq 0x1130
testq %rax, %rax
je 0x1692
movq %rax, %rbx
addq %rbp, %r14
movq %rax, %rdi
leaq 0x4da6(%rip), %rsi      # 0x619c
leaq 0x30(%rsp), %rdx
leaq 0x28(%rsp), %rcx
xorl %eax, %eax
callq 0x1030
movq %rbx, %rdi
callq 0x1050
movb $0x1, 0x10(%r14)
movl 0x6cd6(%rip), %eax      # 0x80f0
cmpq %rax, %r13
jne 0x1426
movb $0x1, 0x6f8e(%rip)      # 0x83b4
leaq 0x4c8a(%rip), %rdi      # 0x60b7
leaq 0x4d16(%rip), %rsi      # 0x614a
callq 0x1130
testq %rax, %rax
je 0x16b1
movq %rax, %r15
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
leaq 0x4d60(%rip), %rsi      # 0x61b4
movl %r13d, %edx
xorl %eax, %eax
callq 0x1160
movq %rbx, %rdi
leaq 0x4d56(%rip), %rsi      # 0x61be
callq 0x1130
testq %rax, %rax
je 0x1654
movq %rax, %rbx
movq %r12, %rdi
movl $0x3e8, %esi            # imm = 0x3E8
movq %r15, %rdx
callq 0x10c0
testq %rax, %rax
je 0x153c
xorl %ebp, %ebp
cmpb $0x20, 0xc0(%rsp)
jne 0x1519
cmpb $0x20, 0xc2(%rsp)
jne 0x1519
movzbl 0xc1(%rsp), %eax
addl $-0x4c, %eax
cmpl $0x7, %eax
ja 0x1519
movl $0x83, %ecx
btl %eax, %ecx
jae 0x1519
leaq 0xc3(%rsp), %rdi
leaq 0x4cfd(%rip), %rsi      # 0x61ce
leaq 0x20(%rsp), %rdx
leaq 0x3c(%rsp), %rcx
xorl %eax, %eax
callq 0x1120
movq 0x20(%rsp), %rax
cmpq 0x30(%rsp), %rax
movl $0x1, %ecx
cmovel %ecx, %ebp
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
cmpq %rcx, %rax
ja 0x150d
testl %ebp, %ebp
je 0x150d
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1090
movq 0x20(%rsp), %rax
cmpq 0x28(%rsp), %rax
je 0x1534
movq %r12, %rdi
movl $0x3e8, %esi            # imm = 0x3E8
movq %r15, %rdx
callq 0x10c0
testq %rax, %rax
jne 0x1494
jmp 0x153c
movq %rbx, %rdi
callq 0x1050
movq %r15, %rdi
callq 0x1050
leaq 0x4c8b(%rip), %rdi      # 0x61d6
movl 0xc(%rsp), %r15d
movl %r15d, %esi
movl 0x10(%rsp), %ebp
movl %ebp, %edx
movl 0x14(%rsp), %ebx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x1070
leaq 0x4b0(%rsp), %r12
movq %r12, %rdi
leaq 0x4c91(%rip), %rsi      # 0x6209
movl %r15d, %edx
movl %ebp, %ecx
movl %ebx, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x1160
movq %r12, %rdi
callq 0x1060
leaq 0x4ca6(%rip), %rdi      # 0x623f
leaq 0x4baa(%rip), %rsi      # 0x614a
callq 0x1130
testq %rax, %rax
je 0x1673
movq %rax, %rbx
movq %rax, %rdi
leaq 0x4c98(%rip), %rsi      # 0x6253
leaq 0x1c(%rsp), %rdx
leaq 0x8(%rsp), %rcx
leaq 0x18(%rsp), %r8
xorl %eax, %eax
callq 0x1030
movq %rbx, %rdi
callq 0x1050
movl 0x1c(%rsp), %ecx
movl %ecx, 0x14(%r14)
movl 0x8(%rsp), %r8d
movl %r8d, 0x18(%r14)
movl 0x18(%rsp), %r9d
movl %r9d, 0x1c(%r14)
movq 0x8(%r14), %rdx
leaq 0x4c5e(%rip), %rdi      # 0x625c
movl %r13d, %esi
xorl %eax, %eax
callq 0x1070
movl 0x6ae2(%rip), %eax      # 0x80f0
cmpq %rax, %r13
leaq 0x6da8(%rip), %r15      # 0x83c0
leaq 0x6db1(%rip), %rbp      # 0x83d0
jne 0x162b
movl 0x8(%rsp), %eax
movl %eax, 0x6ac9(%rip)      # 0x80f4
leaq 0xc0(%rsp), %r12
incq %r13
movslq (%r15), %rbx
cmpq %rbx, %r13
jl 0x1334
addq $0x6b8, %rsp            # imm = 0x6B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4b65(%rip), %rdi      # 0x61c0
leaq 0x4af4(%rip), %rsi      # 0x6156
leaq 0x4afa(%rip), %rcx      # 0x6163
movl $0x63, %edx
callq 0x1080
leaq 0x4bd3(%rip), %rdi      # 0x624d
leaq 0x4ad5(%rip), %rsi      # 0x6156
leaq 0x4adb(%rip), %rcx      # 0x6163
movl $0x92, %edx
callq 0x1080
leaq 0x4ab3(%rip), %rdi      # 0x614c
leaq 0x4ab6(%rip), %rsi      # 0x6156
leaq 0x4abc(%rip), %rcx      # 0x6163
movl $0x50, %edx
callq 0x1080
leaq 0x4aee(%rip), %rdi      # 0x61a6
leaq 0x4a97(%rip), %rsi      # 0x6156
leaq 0x4a9d(%rip), %rcx      # 0x6163
movl $0x5d, %edx
callq 0x1080