// File: martinferianc[P]CPUSimulator-EIE2/src/shared/mips_test_framework.cpp
// Function: mips_test_end_suite
void mips_test_end_suite()
{
    if(!sg_started){
        fprintf(stderr, "Error:mips_test_finish_suite - Test suite has not been started with mips_test_begin_suite.\n");
        exit(1);
    }
    if(sg_tests.size()==0){
        fprintf(stderr, "Error:mips_test_finish_suite - No tests have been executed.\n");
        exit(1);
    }
    if(sg_tests.back().status==-1){
        fprintf(stderr, "Error:mips_test_finish_suite - The final test has not been completed yet.\n");
        exit(1);
    }
    
    // Now we will go through an collect some statistics about what happened
    
    // Build a map from instruction name to a pair of (tests,passed)
    typedef std::map<std::string, std::pair<int,int> > stats_t;
    stats_t statistics;
    
    for(unsigned i=0; i<sg_tests.size(); i++){
        test_info_t info=sg_tests[i];
        
        statistics[info.instruction].first++;   // count all tests
        if(info.status==1){
            statistics[info.instruction].second++;  // count the ones that passed
        }
    }
    
    fprintf(stderr, "\n");
    fprintf(stderr, "| Instruction |  tests | passed | success |\n");
    fprintf(stderr, "+-------------+--------+--------+---------+\n");
    
    // Work out what happened for each instruction
    int totalTested=0;
    int totalNotWorking=0;
    int totalPartiallyWorking=0;
    int totalFullyWorking=0;
    
    stats_t::const_iterator it=statistics.begin();
    while(it!=statistics.end()){
        std::string name=it->first;
        int total=it->second.first;
        int passed=it->second.second;
        
        totalTested++;
        if(passed==0){
            totalNotWorking++;
        }else if(passed<total){
            totalPartiallyWorking++;
        }else{
            totalFullyWorking++;
        }
            
        fprintf(stderr, "|%12s |   %4u |   %4u |  %5.1f%% |\n", name.c_str(), total, passed, 100.0*passed/(double)total);
        
        if(sg_knownInstructions.find(name)==sg_knownInstructions.end()){
            fprintf(stderr, "+ Warning: previous instruction not known +\n");
        }
        
        ++it;
    }
   
    fprintf(stderr, "+-------------+--------+--------+---------+\n"); 
    fprintf(stderr, "\n");
    fprintf(stderr, "Total instructions tested: %3u\n", totalTested);
    fprintf(stderr, "Fully working :            %3u (%5.1f%%)\n", totalFullyWorking, 100.0*totalFullyWorking/(double)totalTested);
    fprintf(stderr, "Partially working :        %3u (%5.1f%%)\n", totalPartiallyWorking, 100.0*totalPartiallyWorking/(double)totalTested);
    fprintf(stderr, "Not working at all :       %3u (%5.1f%%)\n", totalNotWorking, 100.0*totalNotWorking/(double)totalTested);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
testb $0x1, 0x156be(%rip)     # 0x192b0
jne 0x3c16
movq 0x153d5(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe6c9(%rip), %rsi      # 0x122ce
movb $0x0, %al
callq 0x33c0
movl $0x1, %edi
callq 0x3320
leaq 0x1564b(%rip), %rdi     # 0x19268
callq 0x4300
cmpq $0x0, %rax
jne 0x3c4a
movq 0x153a1(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe6f1(%rip), %rsi      # 0x1232a
movb $0x0, %al
callq 0x33c0
movl $0x1, %edi
callq 0x3320
leaq 0x15617(%rip), %rdi     # 0x19268
callq 0x4330
cmpl $-0x1, 0x28(%rax)
jne 0x3c7e
movq 0x1536d(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe6fa(%rip), %rsi      # 0x12367
movb $0x0, %al
callq 0x33c0
movl $0x1, %edi
callq 0x3320
leaq -0x30(%rbp), %rdi
callq 0x4560
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq %rax, -0x108(%rbp)
leaq 0x155c9(%rip), %rdi     # 0x19268
callq 0x4300
movq %rax, %rcx
movq -0x108(%rbp), %rax
cmpq %rcx, %rax
jae 0x3d7f
movl -0x34(%rbp), %eax
movl %eax, %esi
leaq 0x155a5(%rip), %rdi     # 0x19268
callq 0x4580
movq %rax, %rsi
leaq -0x88(%rbp), %rdi
callq 0x45a0
jmp 0x3cd9
leaq -0x80(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x4620
movq %rax, -0x110(%rbp)
jmp 0x3cef
movq -0x110(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
cmpl $0x1, -0x60(%rbp)
jne 0x3d65
leaq -0x80(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x4620
movq %rax, -0x118(%rbp)
jmp 0x3d19
movq -0x118(%rbp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x3d65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x411d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x4530
jmp 0x411d
leaq -0x88(%rbp), %rdi
callq 0x4530
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3c8e
movq 0x1524a(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xed83(%rip), %rsi      # 0x12b13
movb $0x0, %al
callq 0x33c0
movq 0x15232(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe60a(%rip), %rsi      # 0x123b2
movb $0x0, %al
callq 0x33c0
movq 0x1521a(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe61f(%rip), %rsi      # 0x123df
movb $0x0, %al
callq 0x33c0
movl $0x0, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movl $0x0, -0xa0(%rbp)
movl $0x0, -0xa4(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x4700
movq %rax, -0xb8(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x4730
leaq -0x30(%rbp), %rdi
callq 0x4780
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x4730
leaq -0xb0(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x4750
testb $0x1, %al
jne 0x3e51
jmp 0x4003
leaq -0xb0(%rbp), %rdi
callq 0x47b0
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x3120
jmp 0x3e6e
leaq -0xb0(%rbp), %rdi
callq 0x47b0
movl 0x20(%rax), %eax
movl %eax, -0xec(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x47b0
movl 0x24(%rax), %eax
movl %eax, -0xf0(%rbp)
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
cmpl $0x0, -0xf0(%rbp)
jne 0x3ec1
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x3ef1
movl -0xf0(%rbp), %eax
cmpl -0xec(%rbp), %eax
jge 0x3ee0
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x3eef
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x3ef1
movq 0x150d8(%rip), %rax     # 0x18fd0
movq (%rax), %rax
movq %rax, -0x130(%rbp)
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x3110
movq -0x130(%rbp), %rdi
movq %rax, %rdx
movl -0xec(%rbp), %ecx
movl -0xf0(%rbp), %r8d
cvtsi2sd %r8d, %xmm0
movsd 0xe0cf(%rip), %xmm1     # 0x12008
mulsd %xmm1, %xmm0
cvtsi2sd %ecx, %xmm1
divsd %xmm1, %xmm0
leaq 0xe4c0(%rip), %rsi      # 0x1240c
movb $0x1, %al
callq 0x33c0
movq -0x128(%rbp), %rsi
leaq 0x1531f(%rip), %rdi     # 0x19280
callq 0x4450
movq %rax, -0x120(%rbp)
jmp 0x3f6f
movq -0x120(%rbp), %rax
movq %rax, -0xf8(%rbp)
leaq 0x152fc(%rip), %rdi     # 0x19280
callq 0x4490
movq %rax, -0x100(%rbp)
leaq -0xf8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x4420
testb $0x1, %al
jne 0x3fa9
jmp 0x3fe6
movq 0x15020(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe476(%rip), %rsi      # 0x12430
movb $0x0, %al
callq 0x33c0
jmp 0x3fe6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x3170
jmp 0x411d
leaq -0xb0(%rbp), %rdi
callq 0x47d0
leaq -0xe8(%rbp), %rdi
callq 0x3170
jmp 0x3e12
movq 0x14fc6(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xe3cb(%rip), %rsi      # 0x123df
movb $0x0, %al
callq 0x33c0
movq 0x14fae(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
leaq 0xeae7(%rip), %rsi      # 0x12b13
movb $0x0, %al
callq 0x33c0
movq 0x14f96(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
movl -0x98(%rbp), %edx
leaq 0xe413(%rip), %rsi      # 0x1245d
movb $0x0, %al
callq 0x33c0
movq 0x14f78(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
movl -0xa4(%rbp), %edx
cvtsi2sdl -0xa4(%rbp), %xmm1
movsd 0xdf97(%rip), %xmm0     # 0x12008
mulsd %xmm1, %xmm0
cvtsi2sdl -0x98(%rbp), %xmm1
divsd %xmm1, %xmm0
leaq 0xe3f5(%rip), %rsi      # 0x1247d
movb $0x1, %al
callq 0x33c0
movq 0x14f3a(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
movl -0xa0(%rbp), %edx
cvtsi2sdl -0xa0(%rbp), %xmm1
movsd 0xdf59(%rip), %xmm0     # 0x12008
mulsd %xmm1, %xmm0
cvtsi2sdl -0x98(%rbp), %xmm1
divsd %xmm1, %xmm0
leaq 0xe3e1(%rip), %rsi      # 0x124a7
movb $0x1, %al
callq 0x33c0
movq 0x14efc(%rip), %rax     # 0x18fd0
movq (%rax), %rdi
movl -0x9c(%rbp), %edx
cvtsi2sdl -0x9c(%rbp), %xmm1
movsd 0xdf1b(%rip), %xmm0     # 0x12008
mulsd %xmm1, %xmm0
cvtsi2sdl -0x98(%rbp), %xmm1
divsd %xmm1, %xmm0
leaq 0xe3cd(%rip), %rsi      # 0x124d1
movb $0x1, %al
callq 0x33c0
leaq -0x30(%rbp), %rdi
callq 0x4800
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x4800
movq -0x90(%rbp), %rdi
callq 0x3440
nopw %cs:(%rax,%rax)
nopl (%rax)