// File: kernel.cpp
#include "loop_103.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(); }

uint8_t *NOINLINE skip_whitespace(uint8_t *p, uint8_t *end) {
  svuint8_t pat = svreinterpret_u8(svdup_u32(0x200A0D09));

  uint64_t ptr;
  svbool_t pg;
  FOR_LOOP_8(, ptr, (uint64_t)p, (uint64_t)end, pg) {
    svuint8_t c = svld1(pg, (uint8_t *)ptr);
    svbool_t pm = svnmatch(pg, c, pat);
    if (svptest_any(svptrue_b8(), pm)) {
      pm = svbrkb_z(pg, pm);
      ptr += svcntp_b8(pm, pm);
      break;
    }
  }

  return ptr < (uint64_t)end ? (uint8_t *)ptr : end;
}