/*

  This program is part of the TACLeBench benchmark suite.
  Version 2.0

  Name: bsort

  Author: unknown

  Function: A program for testing the basic loop constructs,
            integer comparisons, and simple array handling by
            sorting 100 integers

  Source: MRTC
          http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bsort100/bsort100.c

  Original name: bsort100

  Changes: See ChangeLog.txt

  License: May be used, modified, and re-distributed freely.

*/

/*
  Forward declaration of functions
*/

// Wasm loop bounds




__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);

__attribute__((always_inline)) static inline void bsort_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void);
__attribute__((always_inline)) static inline int bsort_return(void);
__attribute__((always_inline)) static inline int bsort_Initialize(int Array[]);
__attribute__((always_inline)) static inline int bsort_BubbleSort(int Array[]);

/*
  Declaration of global variables
*/

#define bsort_SIZE 100

static int bsort_Array[bsort_SIZE];

/*
  Initialization- and return-value-related functions
*/

/* Initializes given array with randomly generated integers. */
__attribute__((always_inline)) static inline int
bsort_Initialize(int Array[]) {
    int Index;

    __pragma_loopbound(100, 100);
    for (Index = 0; Index < bsort_SIZE; Index++)
        Array[Index] = (Index + 1) * -1;

    return 0;
}

__attribute__((always_inline)) static inline void
bsort_init(void) {
    bsort_Initialize(bsort_Array);
}

__attribute__((always_inline)) static inline int
bsort_return(void) {
    int Sorted = 1;
    int Index;

    __pragma_loopbound(99, 99);
    for (Index = 0; Index < bsort_SIZE - 1; Index++)
        Sorted = Sorted && (bsort_Array[Index] < bsort_Array[Index + 1]);

    return 1 - Sorted;
}

/*
  Core benchmark functions
*/

/* Sorts an array of integers of size bsort_SIZE in ascending
   order with bubble sort. */
__attribute__((always_inline)) static inline int
bsort_BubbleSort(int Array[]) {
    int Sorted = 0;
    int Temp, Index, i;

    __pragma_loopbound(99, 99);
    for (i = 0; i < bsort_SIZE - 1; i++) {
        Sorted = 1;
        __pragma_loopbound(3, 99);
        for (Index = 0; Index < bsort_SIZE - 1; Index++) {
            if (Index > bsort_SIZE - i)
                break;
            if (Array[Index] > Array[Index + 1]) {
                Temp = Array[Index];
                Array[Index] = Array[Index + 1];
                Array[Index + 1] = Temp;
                Sorted = 0;
            }
        }

        if (Sorted)
            break;
    }

    return 0;
}

__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void) {
    bsort_BubbleSort(bsort_Array);
}

/*
  Main function
*/

__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
    bsort_init();
    bsort_main();

    return bsort_return();
}
