text: #include "crypto_core_weightsntrup653.h"
  #include "crypto_encode_int16.h"
  #include "params.h"
  #include <immintrin.h>
  
  #define int8 int8_t
  #define int16 int16_t
  
  
  /* out = little-endian weight of bottom bits of in */
  int PQCLEAN_SNTRUP653_AVX2_crypto_core_weightsntrup653(unsigned char *outbytes, const unsigned char *inbytes) {
      int8 *in = (void *) inbytes;
      int i;
      __m256i sum, sumhi;
      int16 weight;
  
      sum = _mm256_loadu_si256((__m256i *) (in + p - 32));
      sum &= _mm256_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  
      for (i = p - 32; i >= 0; i -= 32) {
          __m256i bits = _mm256_loadu_si256((__m256i *) in);
          bits &= _mm256_set1_epi8(1);
          sum = _mm256_add_epi8(sum, bits);
          in += 32;
      }
  
      /* sum is 32xint8; want to add these int8 */
      sumhi = _mm256_srli_epi16(sum, 8);
      sum &= _mm256_set1_epi16(0xff);
      sum = _mm256_add_epi16(sum, sumhi);
  
      /* sum is 16xint16; want to add these int16 */
      sum = _mm256_hadd_epi16(sum, sum);
      /* want sum[0]+sum[1]+sum[2]+sum[3]+sum[8]+sum[9]+sum[10]+sum[11] */
      sum = _mm256_hadd_epi16(sum, sum);
      /* want sum[0]+sum[1]+sum[8]+sum[9] */
      sum = _mm256_hadd_epi16(sum, sum);
      /* want sum[0]+sum[8] */
  
      weight = (int16) _mm256_extract_epi16(sum, 0);
      weight += (int16) _mm256_extract_epi16(sum, 8);
  
      PQCLEAN_SNTRUP653_AVX2_crypto_encode_int16(outbytes, &weight);
      return 0;
  }
  