/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <tmmintrin.h> /* SSSE3 */

#include "vp8/encoder/block.h"

/* bitscan reverse (bsr) */
#if defined(_MSC_VER)
#include <intrin.h>
#pragma intrinsic(_BitScanReverse)
static int bsr(int mask) {
  unsigned long eob;
  _BitScanReverse(&eob, mask);
  eob++;
  if (mask == 0)
    eob = 0;
  return eob;
}
#else
static int bsr(int mask) {
  int eob;
#if defined(__GNUC__) && __GNUC__
  __asm__ __volatile__("bsr %1, %0" : "=r" (eob) : "r" (mask) : "flags");
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
  asm volatile("bsr %1, %0" : "=r" (eob) : "r" (mask) : "flags");
#endif
  eob++;
  if (mask == 0)
    eob = 0;
  return eob;
}
#endif

void vp8_fast_quantize_b_ssse3(BLOCK *b, BLOCKD *d) {
  int eob, mask;

  __m128i z0 = _mm_load_si128((__m128i *)(b->coeff));
  __m128i z1 = _mm_load_si128((__m128i *)(b->coeff + 8));
  __m128i round0 = _mm_load_si128((__m128i *)(b->round));
  __m128i round1 = _mm_load_si128((__m128i *)(b->round + 8));
  __m128i quant_fast0 = _mm_load_si128((__m128i *)(b->quant_fast));
  __m128i quant_fast1 = _mm_load_si128((__m128i *)(b->quant_fast + 8));
  __m128i dequant0 = _mm_load_si128((__m128i *)(d->dequant));
  __m128i dequant1 = _mm_load_si128((__m128i *)(d->dequant + 8));

  __m128i sz0, sz1, x, x0, x1, y0, y1, zeros, abs0, abs1;

  DECLARE_ALIGNED(16, const uint8_t, pshufb_zig_zag_mask[16]) =
    { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 };
  __m128i zig_zag = _mm_load_si128((const __m128i *)pshufb_zig_zag_mask);

  /* sign of z: z >> 15 */
  sz0 = _mm_srai_epi16(z0, 15);
  sz1 = _mm_srai_epi16(z1, 15);

  /* x = abs(z) */
  x0 = _mm_abs_epi16(z0);
  x1 = _mm_abs_epi16(z1);

  /* x += round */
  x0 = _mm_add_epi16(x0, round0);
  x1 = _mm_add_epi16(x1, round1);

  /* y = (x * quant) >> 16 */
  y0 = _mm_mulhi_epi16(x0, quant_fast0);
  y1 = _mm_mulhi_epi16(x1, quant_fast1);

  /* ASM saves Y for EOB */
  /* I think we can ignore that because adding the sign doesn't change anything
   * and multiplying 0 by dequant is OK as well */
  abs0 = y0;
  abs1 = y1;

  /* Restore the sign bit. */
  y0 = _mm_xor_si128(y0, sz0);
  y1 = _mm_xor_si128(y1, sz1);
  x0 = _mm_sub_epi16(y0, sz0);
  x1 = _mm_sub_epi16(y1, sz1);

  /* qcoeff = x */
  _mm_store_si128((__m128i *)(d->qcoeff), x0);
  _mm_store_si128((__m128i *)(d->qcoeff + 8), x1);

  /* x * dequant */
  x0 = _mm_mullo_epi16(x0, dequant0);
  x1 = _mm_mullo_epi16(x1, dequant1);

  /* dqcoeff = x * dequant */
  _mm_store_si128((__m128i *)(d->dqcoeff), x0);
  _mm_store_si128((__m128i *)(d->dqcoeff + 8), x1);

  zeros = _mm_setzero_si128();

  x0 = _mm_cmpgt_epi16(abs0, zeros);
  x1 = _mm_cmpgt_epi16(abs1, zeros);

  x = _mm_packs_epi16(x0, x1);

  x = _mm_shuffle_epi8(x, zig_zag);

  mask = _mm_movemask_epi8(x);

  eob = bsr(mask);

  *d->eob = 0xFF & eob;
}
