#include <stdio.h>
#include <stdlib.h>
#include <math.h>



int main() {
    srand(0);
    int randomNumbers[ELEMENTS];
    for (int i = 0; i < ELEMENTS; i++) {
        randomNumbers[i] = rand() % 2;
    }

    int sum = 0;

    long long cyclesStart;
    asm volatile("csrr %0, cycle" : "=r" (cyclesStart));

    for (int i = 0; i < ELEMENTS; i++) {
        #if defined(PREDICTABLE) && PREDICTABLE == 0
        int value = randomNumbers[i];
        #else
        int value = i % 2;
        #endif
        
        #if defined(SETUP) && SETUP == 1
        asm volatile("nop":::"memory");
        #else
        
        #if defined(VARIANT) && VARIANT == 0
        // Branchy
            asm volatile(
                "beqz %[value], end%=\n\t"
                "addi %[sum], %[sum], 1\n\t"
                "end%=:"
                : [sum] "+r" (sum)
                : [value] "r" (value)
                : "cc"
            );
        #elif defined(VARIANT) && VARIANT == 1
        // Branch free
            asm volatile(
                "sltiu a0, %[value], 1\n\t"
                "add %[sum], %[sum], a0\n\t"
                : [sum] "+r" (sum)
                : [value] "r" (value)
                : "a0"
            );
        #elif defined(VARIANT) && VARIANT == 2
            asm volatile(
                "bms problematicbranch%=,branchfree%=,10\n"

                "problematicbranch%=:\n\t"
                "beqz %[value], end%=\n\t"
                "addi %[sum], %[sum], 1\n\t"
                "j end%=\n"

                "branchfree%=:\n\t"
                "seqz a0, %[value]\n\t"
                "bjr a0, problematicbranch%=, end%=\n\t"
                "add %[sum], %[sum], a0\n\t"

                "end%=:"
                : [sum] "+r" (sum)
                : [value] "r" (value)
                : "a0", "cc"
            );
        #endif
        #endif
    }

    long long cyclesEnd;
    asm volatile("csrr %0, cycle" : "=r" (cyclesEnd));

    printf("Sum: %d\n", sum);
    printf("Cycles: %lld\n", cyclesEnd - cyclesStart);

    return 0;
}