Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/media/libwebp/src/dsp/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 38 kB image not shown  

Quelle  lossless_mips_dsp_r2.c   Sprache: C

 
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING 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.
// -----------------------------------------------------------------------------
//
// Image transforms and color space conversion methods for lossless decoder.
//
// Author(s):  Djordje Pesut    (djordje.pesut@imgtec.com)
//             Jovan Zelincevic (jovan.zelincevic@imgtec.com)

#include "src/dsp/dsp.h"

#if defined(WEBP_USE_MIPS_DSP_R2)

#include "src/dsp/lossless.h"
#include "src/dsp/lossless_common.h"

#define MAP_COLOR_FUNCS(FUNC_NAME, TYPE, GET_INDEX, GET_VALUE)                 \
static void FUNC_NAME(const TYPE* src,                                         \
                      const uint32_t* const color_map,                         \
                      TYPE* dst, int y_start, int y_end,                       \
                      int width) {                                             \
  int y;                                                                       \
  for (y = y_start; y < y_end; ++y) {                                          \
    int x;                                                                     \
    for (x = 0; x < (width >> 2); ++x) {                                       \
      int tmp1, tmp2, tmp3, tmp4;                                              \
      __asm__ volatile (                                                       \
      ".ifc " #TYPE ", uint8_t \n\t"                  \
        "lbu %[tmp1], 0(%[src]) \n\t"                  \
        "lbu %[tmp2], 1(%[src]) \n\t"                  \
        "lbu %[tmp3], 2(%[src]) \n\t"                  \
        "lbu %[tmp4], 3(%[src]) \n\t"                  \
        "addiu %[src], %[src], 4 \n\t"                  \
      ".endif \n\t"                  \
      ".ifc " #TYPE ", uint32_t \n\t"                  \
        "lw %[tmp1], 0(%[src]) \n\t"                  \
        "lw %[tmp2], 4(%[src]) \n\t"                  \
        "lw %[tmp3], 8(%[src]) \n\t"                  \
        "lw %[tmp4], 12(%[src]) \n\t"                  \
        "ext %[tmp1], %[tmp1], 8, 8 \n\t"                  \
        "ext %[tmp2], %[tmp2], 8, 8 \n\t"                  \
        "ext %[tmp3], %[tmp3], 8, 8 \n\t"                  \
        "ext %[tmp4], %[tmp4], 8, 8 \n\t"                  \
        "addiu %[src], %[src], 16 \n\t"                  \
      ".endif \n\t"                  \
        "sll %[tmp1], %[tmp1], 2 \n\t"                  \
        "sll %[tmp2], %[tmp2], 2 \n\t"                  \
        "sll %[tmp3], %[tmp3], 2 \n\t"                  \
        "sll %[tmp4], %[tmp4], 2 \n\t"                  \
        "lwx %[tmp1], %[tmp1](%[color_map]) \n\t"                  \
        "lwx %[tmp2], %[tmp2](%[color_map]) \n\t"                  \
        "lwx %[tmp3], %[tmp3](%[color_map]) \n\t"                  \
        "lwx %[tmp4], %[tmp4](%[color_map]) \n\t"                  \
      ".ifc " #TYPE ", uint8_t \n\t"                  \
        "ext %[tmp1], %[tmp1], 8, 8 \n\t"                  \
        "ext %[tmp2], %[tmp2], 8, 8 \n\t"                  \
        "ext %[tmp3], %[tmp3], 8, 8 \n\t"                  \
        "ext %[tmp4], %[tmp4], 8, 8 \n\t"                  \
        "sb %[tmp1], 0(%[dst]) \n\t"                  \
        "sb %[tmp2], 1(%[dst]) \n\t"                  \
        "sb %[tmp3], 2(%[dst]) \n\t"                  \
        "sb %[tmp4], 3(%[dst]) \n\t"                  \
        "addiu %[dst], %[dst], 4 \n\t"                  \
      ".endif \n\t"                  \
      ".ifc " #TYPE ", uint32_t \n\t"                  \
        "sw %[tmp1], 0(%[dst]) \n\t"                  \
        "sw %[tmp2], 4(%[dst]) \n\t"                  \
        "sw %[tmp3], 8(%[dst]) \n\t"                  \
        "sw %[tmp4], 12(%[dst]) \n\t"                  \
        "addiu %[dst], %[dst], 16 \n\t"                  \
      ".endif \n\t"                  \
        : [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2), [tmp3]"=&r"(tmp3),             \
          [tmp4]"=&r"(tmp4), [src]"+&r"(src), [dst]"+r"(dst)                   \
        : [color_map]"r"(color_map)                                            \
        : "memory"                                                             \
      );                                                                       \
    }                                                                          \
    for (x = 0; x < (width & 3); ++x) {                                        \
      *dst++ = GET_VALUE(color_map[GET_INDEX(*src++)]);                        \
    }                                                                          \
  }                                                                            \
}

MAP_COLOR_FUNCS(MapARGB_MIPSdspR2, uint32_t, VP8GetARGBIndex, VP8GetARGBValue)
MAP_COLOR_FUNCS(MapAlpha_MIPSdspR2, uint8_t, VP8GetAlphaIndex, VP8GetAlphaValue)

#undef MAP_COLOR_FUNCS

static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
                                                   uint32_t c2) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  __asm__ volatile (
    "preceu.ph.qbr %[temp1], %[c0] \n\t"
    "preceu.ph.qbl %[temp2], %[c0] \n\t"
    "preceu.ph.qbr %[temp3], %[c1] \n\t"
    "preceu.ph.qbl %[temp4], %[c1] \n\t"
    "preceu.ph.qbr %[temp5], %[c2] \n\t"
    "preceu.ph.qbl %[temp0], %[c2] \n\t"
    "subq.ph %[temp3], %[temp3], %[temp5] \n\t"
    "subq.ph %[temp4], %[temp4], %[temp0] \n\t"
    "addq.ph %[temp1], %[temp1], %[temp3] \n\t"
    "addq.ph %[temp2], %[temp2], %[temp4] \n\t"
    "shll_s.ph %[temp1], %[temp1], 7 \n\t"
    "shll_s.ph %[temp2], %[temp2], 7 \n\t"
    "precrqu_s.qb.ph %[temp2], %[temp2], %[temp1] \n\t"
    : [temp0]"=r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5)
    : [c0]"r"(c0), [c1]"r"(c1), [c2]"r"(c2)
    : "memory"
  );
  return temp2;
}

static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
                                                   uint32_t c2) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  __asm__ volatile (
    "adduh.qb %[temp5], %[c0], %[c1] \n\t"
    "preceu.ph.qbr %[temp3], %[c2] \n\t"
    "preceu.ph.qbr %[temp1], %[temp5] \n\t"
    "preceu.ph.qbl %[temp2], %[temp5] \n\t"
    "preceu.ph.qbl %[temp4], %[c2] \n\t"
    "subq.ph %[temp3], %[temp1], %[temp3] \n\t"
    "subq.ph %[temp4], %[temp2], %[temp4] \n\t"
    "shrl.ph %[temp5], %[temp3], 15 \n\t"
    "shrl.ph %[temp0], %[temp4], 15 \n\t"
    "addq.ph %[temp3], %[temp3], %[temp5] \n\t"
    "addq.ph %[temp4], %[temp0], %[temp4] \n\t"
    "shra.ph %[temp3], %[temp3], 1 \n\t"
    "shra.ph %[temp4], %[temp4], 1 \n\t"
    "addq.ph %[temp1], %[temp1], %[temp3] \n\t"
    "addq.ph %[temp2], %[temp2], %[temp4] \n\t"
    "shll_s.ph %[temp1], %[temp1], 7 \n\t"
    "shll_s.ph %[temp2], %[temp2], 7 \n\t"
    "precrqu_s.qb.ph %[temp1], %[temp2], %[temp1] \n\t"
    : [temp0]"=r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [temp4]"=r"(temp4), [temp5]"=&r"(temp5)
    : [c0]"r"(c0), [c1]"r"(c1), [c2]"r"(c2)
    : "memory"
  );
  return temp1;
}

static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  __asm__ volatile (
    "cmpgdu.lt.qb %[temp1], %[c], %[b] \n\t"
    "pick.qb %[temp1], %[b], %[c] \n\t"
    "pick.qb %[temp2], %[c], %[b] \n\t"
    "cmpgdu.lt.qb %[temp4], %[c], %[a] \n\t"
    "pick.qb %[temp4], %[a], %[c] \n\t"
    "pick.qb %[temp5], %[c], %[a] \n\t"
    "subu.qb %[temp3], %[temp1], %[temp2] \n\t"
    "subu.qb %[temp0], %[temp4], %[temp5] \n\t"
    "raddu.w.qb %[temp3], %[temp3] \n\t"
    "raddu.w.qb %[temp0], %[temp0] \n\t"
    "subu %[temp3], %[temp3], %[temp0] \n\t"
    "slti %[temp0], %[temp3], 0x1 \n\t"
    "movz %[a], %[b], %[temp0] \n\t"
    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp0]"=&r"(temp0),
      [a]"+&r"(a)
    : [b]"r"(b), [c]"r"(c)
  );
  return a;
}

static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
  __asm__ volatile (
    "adduh.qb %[a0], %[a0], %[a1] \n\t"
    : [a0]"+r"(a0)
    : [a1]"r"(a1)
  );
  return a0;
}

static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
  return Average2(Average2(a0, a2), a1);
}

static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
                                     uint32_t a2, uint32_t a3) {
  return Average2(Average2(a0, a1), Average2(a2, a3));
}

static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
                                     const uint32_t* const top) {
  return Average3(*left, top[0], top[1]);
}

static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
                                     const uint32_t* const top) {
  return Average2(*left, top[-1]);
}

static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
                                     const uint32_t* const top) {
  return Average2(*left, top[0]);
}

static uint32_t Predictor8_MIPSdspR2(const uint32_t* const left,
                                     const uint32_t* const top) {
  (void)left;
  return Average2(top[-1], top[0]);
}

static uint32_t Predictor9_MIPSdspR2(const uint32_t* const left,
                                     const uint32_t* const top) {
  (void)left;
  return Average2(top[0], top[1]);
}

static uint32_t Predictor10_MIPSdspR2(const uint32_t* const left,
                                      const uint32_t* const top) {
  return Average4(*left, top[-1], top[0], top[1]);
}

static uint32_t Predictor11_MIPSdspR2(const uint32_t* const left,
                                      const uint32_t* const top) {
  return Select(top[0], *left, top[-1]);
}

static uint32_t Predictor12_MIPSdspR2(const uint32_t* const left,
                                      const uint32_t* const top) {
  return ClampedAddSubtractFull(*left, top[0], top[-1]);
}

static uint32_t Predictor13_MIPSdspR2(const uint32_t* const left,
                                      const uint32_t* const top) {
  return ClampedAddSubtractHalf(*left, top[0], top[-1]);
}

// Add green to blue and red channels (i.e. perform the inverse transform of
// 'subtract green').
static void AddGreenToBlueAndRed_MIPSdspR2(const uint32_t* src, int num_pixels,
                                           uint32_t* dst) {
  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "ext %[temp4], %[temp0], 8, 8 \n\t"
    "ext %[temp5], %[temp1], 8, 8 \n\t"
    "ext %[temp6], %[temp2], 8, 8 \n\t"
    "ext %[temp7], %[temp3], 8, 8 \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "addiu %[dst], %[dst], 16 \n\t"
    "replv.ph %[temp4], %[temp4] \n\t"
    "replv.ph %[temp5], %[temp5] \n\t"
    "replv.ph %[temp6], %[temp6] \n\t"
    "replv.ph %[temp7], %[temp7] \n\t"
    "addu.qb %[temp0], %[temp0], %[temp4] \n\t"
    "addu.qb %[temp1], %[temp1], %[temp5] \n\t"
    "addu.qb %[temp2], %[temp2], %[temp6] \n\t"
    "addu.qb %[temp3], %[temp3], %[temp7] \n\t"
    "sw %[temp0], -16(%[dst]) \n\t"
    "sw %[temp1], -12(%[dst]) \n\t"
    "sw %[temp2], -8(%[dst]) \n\t"
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " sw %[temp3], -4(%[dst]) \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "addiu %[dst], %[dst], 4 \n\t"
    "ext %[temp4], %[temp0], 8, 8 \n\t"
    "replv.ph %[temp4], %[temp4] \n\t"
    "addu.qb %[temp0], %[temp0], %[temp4] \n\t"
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " sw %[temp0], -4(%[dst]) \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [dst]"+&r"(dst), [src]"+&r"(src), [temp0]"=&r"(temp0),
      [temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),
      [temp7]"=&r"(temp7)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

static void TransformColorInverse_MIPSdspR2(const VP8LMultipliers* const m,
                                            const uint32_t* src, int num_pixels,
                                            uint32_t* dst) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  uint32_t argb, argb1, new_red;
  const uint32_t G_to_R = m->green_to_red_;
  const uint32_t G_to_B = m->green_to_blue_;
  const uint32_t R_to_B = m->red_to_blue_;
  const uint32_t* const p_loop_end = src + (num_pixels & ~1);
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop_end], 1f \n\t"
    " nop \n\t"
    "replv.ph %[temp0], %[G_to_R] \n\t"
    "replv.ph %[temp1], %[G_to_B] \n\t"
    "replv.ph %[temp2], %[R_to_B] \n\t"
    "shll.ph %[temp0], %[temp0], 8 \n\t"
    "shll.ph %[temp1], %[temp1], 8 \n\t"
    "shll.ph %[temp2], %[temp2], 8 \n\t"
    "shra.ph %[temp0], %[temp0], 8 \n\t"
    "shra.ph %[temp1], %[temp1], 8 \n\t"
    "shra.ph %[temp2], %[temp2], 8 \n\t"
  "0: \n\t"
    "lw %[argb], 0(%[src]) \n\t"
    "lw %[argb1], 4(%[src]) \n\t"
    "sw %[argb], 0(%[dst]) \n\t"
    "sw %[argb1], 4(%[dst]) \n\t"
    "addiu %[src], %[src], 8 \n\t"
    "addiu %[dst], %[dst], 8 \n\t"
    "precrq.qb.ph %[temp3], %[argb], %[argb1] \n\t"
    "preceu.ph.qbra %[temp3], %[temp3] \n\t"
    "shll.ph %[temp3], %[temp3], 8 \n\t"
    "shra.ph %[temp3], %[temp3], 8 \n\t"
    "mul.ph %[temp5], %[temp3], %[temp0] \n\t"
    "mul.ph %[temp3], %[temp3], %[temp1] \n\t"
    "precrq.ph.w %[new_red], %[argb], %[argb1] \n\t"
    "ins %[argb1], %[argb], 16, 16 \n\t"
    "shra.ph %[temp5], %[temp5], 5 \n\t"
    "shra.ph %[temp3], %[temp3], 5 \n\t"
    "addu.ph %[new_red], %[new_red], %[temp5] \n\t"
    "addu.ph %[argb1], %[argb1], %[temp3] \n\t"
    "preceu.ph.qbra %[temp5], %[new_red] \n\t"
    "shll.ph %[temp4], %[temp5], 8 \n\t"
    "shra.ph %[temp4], %[temp4], 8 \n\t"
    "mul.ph %[temp4], %[temp4], %[temp2] \n\t"
    "sb %[temp5], -2(%[dst]) \n\t"
    "sra %[temp5], %[temp5], 16 \n\t"
    "shra.ph %[temp4], %[temp4], 5 \n\t"
    "addu.ph %[argb1], %[argb1], %[temp4] \n\t"
    "preceu.ph.qbra %[temp3], %[argb1] \n\t"
    "sb %[temp5], -6(%[dst]) \n\t"
    "sb %[temp3], -4(%[dst]) \n\t"
    "sra %[temp3], %[temp3], 16 \n\t"
    "bne %[src], %[p_loop_end], 0b \n\t"
    " sb %[temp3], -8(%[dst]) \n\t"
  "1: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
      [new_red]"=&r"(new_red), [argb]"=&r"(argb),
      [argb1]"=&r"(argb1), [dst]"+&r"(dst), [src]"+&r"(src)
    : [G_to_R]"r"(G_to_R), [R_to_B]"r"(R_to_B),
      [G_to_B]"r"(G_to_B), [p_loop_end]"r"(p_loop_end)
    : "memory""hi""lo"
  );

  // Fall-back to C-version for left-overs.
  if (num_pixels & 1) VP8LTransformColorInverse_C(m, src, 1, dst);
}

static void ConvertBGRAToRGB_MIPSdspR2(const uint32_t* src,
                                       int num_pixels, uint8_t* dst) {
  int temp0, temp1, temp2, temp3;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "ins %[temp3], %[temp2], 24, 8 \n\t"
    "sll %[temp2], %[temp2], 8 \n\t"
    "rotr %[temp3], %[temp3], 16 \n\t"
    "ins %[temp2], %[temp1], 0, 16 \n\t"
    "sll %[temp1], %[temp1], 8 \n\t"
    "wsbh %[temp3], %[temp3] \n\t"
    "balign %[temp0], %[temp1], 1 \n\t"
    "wsbh %[temp2], %[temp2] \n\t"
    "wsbh %[temp0], %[temp0] \n\t"
    "usw %[temp3], 8(%[dst]) \n\t"
    "rotr %[temp0], %[temp0], 16 \n\t"
    "usw %[temp2], 4(%[dst]) \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "usw %[temp0], 0(%[dst]) \n\t"
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " addiu %[dst], %[dst], 12 \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "wsbh %[temp1], %[temp0] \n\t"
    "addiu %[dst], %[dst], 3 \n\t"
    "ush %[temp1], -2(%[dst]) \n\t"
    "sra %[temp0], %[temp0], 16 \n\t"
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " sb %[temp0], -3(%[dst]) \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

static void ConvertBGRAToRGBA_MIPSdspR2(const uint32_t* src,
                                        int num_pixels, uint8_t* dst) {
  int temp0, temp1, temp2, temp3;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "wsbh %[temp0], %[temp0] \n\t"
    "wsbh %[temp1], %[temp1] \n\t"
    "wsbh %[temp2], %[temp2] \n\t"
    "wsbh %[temp3], %[temp3] \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "balign %[temp0], %[temp0], 1 \n\t"
    "balign %[temp1], %[temp1], 1 \n\t"
    "balign %[temp2], %[temp2], 1 \n\t"
    "balign %[temp3], %[temp3], 1 \n\t"
    "usw %[temp0], 0(%[dst]) \n\t"
    "usw %[temp1], 4(%[dst]) \n\t"
    "usw %[temp2], 8(%[dst]) \n\t"
    "usw %[temp3], 12(%[dst]) \n\t"
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " addiu %[dst], %[dst], 16 \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "wsbh %[temp0], %[temp0] \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "balign %[temp0], %[temp0], 1 \n\t"
    "usw %[temp0], 0(%[dst]) \n\t"
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " addiu %[dst], %[dst], 4 \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

static void ConvertBGRAToRGBA4444_MIPSdspR2(const uint32_t* src,
                                            int num_pixels, uint8_t* dst) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "ext %[temp4], %[temp0], 28, 4 \n\t"
    "ext %[temp5], %[temp0], 12, 4 \n\t"
    "ins %[temp0], %[temp4], 0, 4 \n\t"
    "ext %[temp4], %[temp1], 28, 4 \n\t"
    "ins %[temp0], %[temp5], 16, 4 \n\t"
    "ext %[temp5], %[temp1], 12, 4 \n\t"
    "ins %[temp1], %[temp4], 0, 4 \n\t"
    "ext %[temp4], %[temp2], 28, 4 \n\t"
    "ins %[temp1], %[temp5], 16, 4 \n\t"
    "ext %[temp5], %[temp2], 12, 4 \n\t"
    "ins %[temp2], %[temp4], 0, 4 \n\t"
    "ext %[temp4], %[temp3], 28, 4 \n\t"
    "ins %[temp2], %[temp5], 16, 4 \n\t"
    "ext %[temp5], %[temp3], 12, 4 \n\t"
    "ins %[temp3], %[temp4], 0, 4 \n\t"
    "precr.qb.ph %[temp1], %[temp1], %[temp0] \n\t"
    "ins %[temp3], %[temp5], 16, 4 \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "precr.qb.ph %[temp3], %[temp3], %[temp2] \n\t"
#if (WEBP_SWAP_16BIT_CSP == 1)
    "usw %[temp1], 0(%[dst]) \n\t"
    "usw %[temp3], 4(%[dst]) \n\t"
#else
    "wsbh %[temp1], %[temp1] \n\t"
    "wsbh %[temp3], %[temp3] \n\t"
    "usw %[temp1], 0(%[dst]) \n\t"
    "usw %[temp3], 4(%[dst]) \n\t"
#endif
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " addiu %[dst], %[dst], 8 \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "ext %[temp4], %[temp0], 28, 4 \n\t"
    "ext %[temp5], %[temp0], 12, 4 \n\t"
    "ins %[temp0], %[temp4], 0, 4 \n\t"
    "ins %[temp0], %[temp5], 16, 4 \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "precr.qb.ph %[temp0], %[temp0], %[temp0] \n\t"
#if (WEBP_SWAP_16BIT_CSP == 1)
    "ush %[temp0], 0(%[dst]) \n\t"
#else
    "wsbh %[temp0], %[temp0] \n\t"
    "ush %[temp0], 0(%[dst]) \n\t"
#endif
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " addiu %[dst], %[dst], 2 \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
      [dst]"+&r"(dst), [src]"+&r"(src)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

static void ConvertBGRAToRGB565_MIPSdspR2(const uint32_t* src,
                                          int num_pixels, uint8_t* dst) {
  int temp0, temp1, temp2, temp3, temp4, temp5;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "ext %[temp4], %[temp0], 8, 16 \n\t"
    "ext %[temp5], %[temp0], 5, 11 \n\t"
    "ext %[temp0], %[temp0], 3, 5 \n\t"
    "ins %[temp4], %[temp5], 0, 11 \n\t"
    "ext %[temp5], %[temp1], 5, 11 \n\t"
    "ins %[temp4], %[temp0], 0, 5 \n\t"
    "ext %[temp0], %[temp1], 8, 16 \n\t"
    "ext %[temp1], %[temp1], 3, 5 \n\t"
    "ins %[temp0], %[temp5], 0, 11 \n\t"
    "ext %[temp5], %[temp2], 5, 11 \n\t"
    "ins %[temp0], %[temp1], 0, 5 \n\t"
    "ext %[temp1], %[temp2], 8, 16 \n\t"
    "ext %[temp2], %[temp2], 3, 5 \n\t"
    "ins %[temp1], %[temp5], 0, 11 \n\t"
    "ext %[temp5], %[temp3], 5, 11 \n\t"
    "ins %[temp1], %[temp2], 0, 5 \n\t"
    "ext %[temp2], %[temp3], 8, 16 \n\t"
    "ext %[temp3], %[temp3], 3, 5 \n\t"
    "ins %[temp2], %[temp5], 0, 11 \n\t"
    "append %[temp0], %[temp4], 16 \n\t"
    "ins %[temp2], %[temp3], 0, 5 \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "append %[temp2], %[temp1], 16 \n\t"
#if (WEBP_SWAP_16BIT_CSP == 1)
    "usw %[temp0], 0(%[dst]) \n\t"
    "usw %[temp2], 4(%[dst]) \n\t"
#else
    "wsbh %[temp0], %[temp0] \n\t"
    "wsbh %[temp2], %[temp2] \n\t"
    "usw %[temp0], 0(%[dst]) \n\t"
    "usw %[temp2], 4(%[dst]) \n\t"
#endif
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " addiu %[dst], %[dst], 8 \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "ext %[temp4], %[temp0], 8, 16 \n\t"
    "ext %[temp5], %[temp0], 5, 11 \n\t"
    "ext %[temp0], %[temp0], 3, 5 \n\t"
    "ins %[temp4], %[temp5], 0, 11 \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "ins %[temp4], %[temp0], 0, 5 \n\t"
#if (WEBP_SWAP_16BIT_CSP == 1)
    "ush %[temp4], 0(%[dst]) \n\t"
#else
    "wsbh %[temp4], %[temp4] \n\t"
    "ush %[temp4], 0(%[dst]) \n\t"
#endif
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " addiu %[dst], %[dst], 2 \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
      [dst]"+&r"(dst), [src]"+&r"(src)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

static void ConvertBGRAToBGR_MIPSdspR2(const uint32_t* src,
                                       int num_pixels, uint8_t* dst) {
  int temp0, temp1, temp2, temp3;
  const uint32_t* const p_loop1_end = src + (num_pixels & ~3);
  const uint32_t* const p_loop2_end = src + num_pixels;
  __asm__ volatile (
    ".set push \n\t"
    ".set noreorder \n\t"
    "beq %[src], %[p_loop1_end], 3f \n\t"
    " nop \n\t"
  "0: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "lw %[temp1], 4(%[src]) \n\t"
    "lw %[temp2], 8(%[src]) \n\t"
    "lw %[temp3], 12(%[src]) \n\t"
    "ins %[temp0], %[temp1], 24, 8 \n\t"
    "sra %[temp1], %[temp1], 8 \n\t"
    "ins %[temp1], %[temp2], 16, 16 \n\t"
    "sll %[temp2], %[temp2], 8 \n\t"
    "balign %[temp3], %[temp2], 1 \n\t"
    "addiu %[src], %[src], 16 \n\t"
    "usw %[temp0], 0(%[dst]) \n\t"
    "usw %[temp1], 4(%[dst]) \n\t"
    "usw %[temp3], 8(%[dst]) \n\t"
    "bne %[src], %[p_loop1_end], 0b \n\t"
    " addiu %[dst], %[dst], 12 \n\t"
  "3: \n\t"
    "beq %[src], %[p_loop2_end], 2f \n\t"
    " nop \n\t"
  "1: \n\t"
    "lw %[temp0], 0(%[src]) \n\t"
    "addiu %[src], %[src], 4 \n\t"
    "addiu %[dst], %[dst], 3 \n\t"
    "ush %[temp0], -3(%[dst]) \n\t"
    "sra %[temp0], %[temp0], 16 \n\t"
    "bne %[src], %[p_loop2_end], 1b \n\t"
    " sb %[temp0], -1(%[dst]) \n\t"
  "2: \n\t"
    ".set pop \n\t"
    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
      [temp3]"=&r"(temp3), [dst]"+&r"(dst), [src]"+&r"(src)
    : [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)
    : "memory"
  );
}

//------------------------------------------------------------------------------
// Entry point

extern void VP8LDspInitMIPSdspR2(void);

WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitMIPSdspR2(void) {
  VP8LMapColor32b = MapARGB_MIPSdspR2;
  VP8LMapColor8b = MapAlpha_MIPSdspR2;

  VP8LPredictors[5] = Predictor5_MIPSdspR2;
  VP8LPredictors[6] = Predictor6_MIPSdspR2;
  VP8LPredictors[7] = Predictor7_MIPSdspR2;
  VP8LPredictors[8] = Predictor8_MIPSdspR2;
  VP8LPredictors[9] = Predictor9_MIPSdspR2;
  VP8LPredictors[10] = Predictor10_MIPSdspR2;
  VP8LPredictors[11] = Predictor11_MIPSdspR2;
  VP8LPredictors[12] = Predictor12_MIPSdspR2;
  VP8LPredictors[13] = Predictor13_MIPSdspR2;

  VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed_MIPSdspR2;
  VP8LTransformColorInverse = TransformColorInverse_MIPSdspR2;

  VP8LConvertBGRAToRGB = ConvertBGRAToRGB_MIPSdspR2;
  VP8LConvertBGRAToRGBA = ConvertBGRAToRGBA_MIPSdspR2;
  VP8LConvertBGRAToRGBA4444 = ConvertBGRAToRGBA4444_MIPSdspR2;
  VP8LConvertBGRAToRGB565 = ConvertBGRAToRGB565_MIPSdspR2;
  VP8LConvertBGRAToBGR = ConvertBGRAToBGR_MIPSdspR2;
}

#else  // !WEBP_USE_MIPS_DSP_R2

WEBP_DSP_INIT_STUB(VP8LDspInitMIPSdspR2)

#endif  // WEBP_USE_MIPS_DSP_R2

Messung V0.5
C=95 H=91 G=92

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.