// File: kernel.cpp
#include "loop_121.h"
#include <stdint.h>
#include <arm_sve.h>
#define restrict __restrict
#define SC_SVE_ATTR
#define FOR_COND(P, S, I, N) svptest_first(svptrue_b##S(), P = svwhilelt_b##S(I, N))
#define FOR_LOOP(T, I, M, N, P, S, W) for (T I = M; FOR_COND(P, S, I, N); I += svcnt##W())
#define FOR_LOOP_8(T, I, M, N, P)  FOR_LOOP(T, I, M, N, P, 8, b)
#define FOR_LOOP_16(T, I, M, N, P) FOR_LOOP(T, I, M, N, P, 16, h)
#define FOR_LOOP_32(T, I, M, N, P) FOR_LOOP(T, I, M, N, P, 32, w)
#define FOR_LOOP_64(T, I, M, N, P) FOR_LOOP(T, I, M, N, P, 64, d)
static inline uint32_t get_sve_vl(void) {
  uint64_t vl = 0; asm volatile("incb %[vl], all, mul #8" : [vl] "+r"(vl) : :);
  return (uint32_t)vl;
}
static inline uint32_t get_vl(void) { return get_sve_vl(); }

inline uint32_t find_pivot(uint32_t n, const int32_t * data) {
  struct tuple_32 {
    uint32_t idx;
    int32_t val;
  } t, candidates[3];

  candidates[0].idx = 0;
  candidates[1].idx = n - 1;
  candidates[2].idx = n / 2;

  candidates[0].val = data[candidates[0].idx];
  candidates[1].val = data[candidates[1].idx];
  candidates[2].val = data[candidates[2].idx];

  int i, j;
  for (i = 1; i < 3; i++) {
    t = candidates[i];
    for (j = i - 1; j >= 0 && candidates[j].val > t.val; j--)
      candidates[j + 1] = candidates[j];
    candidates[j + 1] = t;
  }

  return candidates[1].idx;
}