early-access version 1432

This commit is contained in:
pineappleEA
2021-02-09 04:25:58 +01:00
parent de64eab4b4
commit 3d5a9d908a
7336 changed files with 1773492 additions and 111 deletions

92
externals/ffmpeg/libavcodec/mips/Makefile vendored Executable file
View File

@@ -0,0 +1,92 @@
MIPSFPU-OBJS-$(CONFIG_AMRNB_DECODER) += mips/acelp_filters_mips.o \
mips/celp_filters_mips.o \
mips/celp_math_mips.o \
mips/acelp_vectors_mips.o
MIPSFPU-OBJS-$(CONFIG_AMRWB_DECODER) += mips/acelp_filters_mips.o \
mips/celp_filters_mips.o \
mips/amrwbdec_mips.o \
mips/celp_math_mips.o \
mips/acelp_vectors_mips.o
MIPSFPU-OBJS-$(CONFIG_MPEGAUDIODSP) += mips/mpegaudiodsp_mips_float.o
MIPSDSP-OBJS-$(CONFIG_MPEGAUDIODSP) += mips/mpegaudiodsp_mips_fixed.o
MIPSFPU-OBJS-$(CONFIG_FFT) += mips/fft_mips.o
MIPSFPU-OBJS-$(CONFIG_FMTCONVERT) += mips/fmtconvert_mips.o
OBJS-$(CONFIG_AC3DSP) += mips/ac3dsp_mips.o
OBJS-$(CONFIG_AAC_DECODER) += mips/aacdec_mips.o \
mips/aacsbr_mips.o \
mips/sbrdsp_mips.o \
mips/aacpsdsp_mips.o
MIPSDSP-OBJS-$(CONFIG_AAC_ENCODER) += mips/aaccoder_mips.o
MIPSFPU-OBJS-$(CONFIG_AAC_ENCODER) += mips/iirfilter_mips.o
OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_init_mips.o \
mips/hevcpred_init_mips.o
OBJS-$(CONFIG_VP9_DECODER) += mips/vp9dsp_init_mips.o
OBJS-$(CONFIG_VP8_DECODER) += mips/vp8dsp_init_mips.o
OBJS-$(CONFIG_VP3DSP) += mips/vp3dsp_init_mips.o
OBJS-$(CONFIG_H264DSP) += mips/h264dsp_init_mips.o
OBJS-$(CONFIG_H264QPEL) += mips/h264qpel_init_mips.o
OBJS-$(CONFIG_H264CHROMA) += mips/h264chroma_init_mips.o
OBJS-$(CONFIG_H264PRED) += mips/h264pred_init_mips.o
OBJS-$(CONFIG_H263DSP) += mips/h263dsp_init_mips.o
OBJS-$(CONFIG_QPELDSP) += mips/qpeldsp_init_mips.o
OBJS-$(CONFIG_HPELDSP) += mips/hpeldsp_init_mips.o
OBJS-$(CONFIG_BLOCKDSP) += mips/blockdsp_init_mips.o
OBJS-$(CONFIG_PIXBLOCKDSP) += mips/pixblockdsp_init_mips.o
OBJS-$(CONFIG_IDCTDSP) += mips/idctdsp_init_mips.o
OBJS-$(CONFIG_MPEGVIDEO) += mips/mpegvideo_init_mips.o
OBJS-$(CONFIG_MPEGVIDEOENC) += mips/mpegvideoencdsp_init_mips.o
OBJS-$(CONFIG_ME_CMP) += mips/me_cmp_init_mips.o
OBJS-$(CONFIG_MPEG4_DECODER) += mips/xvididct_init_mips.o
OBJS-$(CONFIG_VC1DSP) += mips/vc1dsp_init_mips.o
OBJS-$(CONFIG_WMV2DSP) += mips/wmv2dsp_init_mips.o
OBJS-$(CONFIG_VIDEODSP) += mips/videodsp_init.o
MSA-OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_msa.o \
mips/hevc_mc_uni_msa.o \
mips/hevc_mc_uniw_msa.o \
mips/hevc_mc_bi_msa.o \
mips/hevc_mc_biw_msa.o \
mips/hevc_idct_msa.o \
mips/hevc_lpf_sao_msa.o \
mips/hevcpred_msa.o
MSA-OBJS-$(CONFIG_VP9_DECODER) += mips/vp9_mc_msa.o \
mips/vp9_lpf_msa.o \
mips/vp9_idct_msa.o \
mips/vp9_intra_msa.o
MSA-OBJS-$(CONFIG_VP8_DECODER) += mips/vp8_mc_msa.o \
mips/vp8_idct_msa.o \
mips/vp8_lpf_msa.o
MSA-OBJS-$(CONFIG_VP3DSP) += mips/vp3dsp_idct_msa.o
MSA-OBJS-$(CONFIG_H264DSP) += mips/h264dsp_msa.o \
mips/h264idct_msa.o
MSA-OBJS-$(CONFIG_H264QPEL) += mips/h264qpel_msa.o
MSA-OBJS-$(CONFIG_H264CHROMA) += mips/h264chroma_msa.o
MSA-OBJS-$(CONFIG_H264PRED) += mips/h264pred_msa.o
MSA-OBJS-$(CONFIG_H263DSP) += mips/h263dsp_msa.o
MSA-OBJS-$(CONFIG_QPELDSP) += mips/qpeldsp_msa.o
MSA-OBJS-$(CONFIG_HPELDSP) += mips/hpeldsp_msa.o
MSA-OBJS-$(CONFIG_BLOCKDSP) += mips/blockdsp_msa.o
MSA-OBJS-$(CONFIG_PIXBLOCKDSP) += mips/pixblockdsp_msa.o
MSA-OBJS-$(CONFIG_IDCTDSP) += mips/idctdsp_msa.o \
mips/simple_idct_msa.o
MSA-OBJS-$(CONFIG_MPEGVIDEO) += mips/mpegvideo_msa.o
MSA-OBJS-$(CONFIG_MPEGVIDEOENC) += mips/mpegvideoencdsp_msa.o
MSA-OBJS-$(CONFIG_ME_CMP) += mips/me_cmp_msa.o
MMI-OBJS += mips/constants.o
MMI-OBJS-$(CONFIG_H264DSP) += mips/h264dsp_mmi.o
MMI-OBJS-$(CONFIG_H264CHROMA) += mips/h264chroma_mmi.o
MMI-OBJS-$(CONFIG_H264PRED) += mips/h264pred_mmi.o
MMI-OBJS-$(CONFIG_MPEGVIDEO) += mips/mpegvideo_mmi.o
MMI-OBJS-$(CONFIG_IDCTDSP) += mips/idctdsp_mmi.o \
mips/simple_idct_mmi.o
MMI-OBJS-$(CONFIG_MPEG4_DECODER) += mips/xvid_idct_mmi.o
MMI-OBJS-$(CONFIG_BLOCKDSP) += mips/blockdsp_mmi.o
MMI-OBJS-$(CONFIG_PIXBLOCKDSP) += mips/pixblockdsp_mmi.o
MMI-OBJS-$(CONFIG_H264QPEL) += mips/h264qpel_mmi.o
MMI-OBJS-$(CONFIG_VP8_DECODER) += mips/vp8dsp_mmi.o
MMI-OBJS-$(CONFIG_HPELDSP) += mips/hpeldsp_mmi.o
MMI-OBJS-$(CONFIG_VC1_DECODER) += mips/vc1dsp_mmi.o
MMI-OBJS-$(CONFIG_WMV2DSP) += mips/wmv2dsp_mmi.o
MMI-OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_mmi.o
MMI-OBJS-$(CONFIG_VP3DSP) += mips/vp3dsp_idct_mmi.o
MMI-OBJS-$(CONFIG_VP9_DECODER) += mips/vp9_mc_mmi.o
MSA-OBJS-$(CONFIG_VC1_DECODER) += mips/vc1dsp_msa.o

2502
externals/ffmpeg/libavcodec/mips/aaccoder_mips.c vendored Executable file

File diff suppressed because it is too large Load Diff

442
externals/ffmpeg/libavcodec/mips/aacdec_mips.c vendored Executable file
View File

@@ -0,0 +1,442 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Darko Laus (darko@mips.com)
* Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacdec.c
*/
#include "libavcodec/aac.h"
#include "aacdec_mips.h"
#include "libavcodec/aactab.h"
#include "libavcodec/sinewin.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
static av_always_inline void float_copy(float *dst, const float *src, int count)
{
// Copy 'count' floats from src to dst
const float *loop_end = src + count;
int temp[8];
// count must be a multiple of 8
av_assert2(count % 8 == 0);
// loop unrolled 8 times
__asm__ volatile (
".set push \n\t"
".set noreorder \n\t"
"1: \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"
"lw %[temp4], 16(%[src]) \n\t"
"lw %[temp5], 20(%[src]) \n\t"
"lw %[temp6], 24(%[src]) \n\t"
"lw %[temp7], 28(%[src]) \n\t"
PTR_ADDIU "%[src], %[src], 32 \n\t"
"sw %[temp0], 0(%[dst]) \n\t"
"sw %[temp1], 4(%[dst]) \n\t"
"sw %[temp2], 8(%[dst]) \n\t"
"sw %[temp3], 12(%[dst]) \n\t"
"sw %[temp4], 16(%[dst]) \n\t"
"sw %[temp5], 20(%[dst]) \n\t"
"sw %[temp6], 24(%[dst]) \n\t"
"sw %[temp7], 28(%[dst]) \n\t"
"bne %[src], %[loop_end], 1b \n\t"
PTR_ADDIU "%[dst], %[dst], 32 \n\t"
".set pop \n\t"
: [temp0]"=&r"(temp[0]), [temp1]"=&r"(temp[1]),
[temp2]"=&r"(temp[2]), [temp3]"=&r"(temp[3]),
[temp4]"=&r"(temp[4]), [temp5]"=&r"(temp[5]),
[temp6]"=&r"(temp[6]), [temp7]"=&r"(temp[7]),
[src]"+r"(src), [dst]"+r"(dst)
: [loop_end]"r"(loop_end)
: "memory"
);
}
static av_always_inline int lcg_random(unsigned previous_val)
{
union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
return v.s;
}
static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce)
{
IndividualChannelStream *ics = &sce->ics;
float *in = sce->coeffs;
float *out = sce->ret;
float *saved = sce->saved;
const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
float *buf = ac->buf_mdct;
int i;
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
for (i = 0; i < 1024; i += 128)
ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
} else
ac->mdct.imdct_half(&ac->mdct, buf, in);
/* window overlapping
* NOTE: To simplify the overlapping code, all 'meaningless' short to long
* and long to short transitions are considered to be short to short
* transitions. This leaves just two cases (long to long and short to short)
* with a little special sauce for EIGHT_SHORT_SEQUENCE.
*/
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
} else {
float_copy(out, saved, 448);
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
{
float wi;
float wj;
int i;
float temp0, temp1, temp2, temp3;
float *dst0 = out + 448 + 0*128;
float *dst1 = dst0 + 64 + 63;
float *dst2 = saved + 63;
float *win0 = (float*)swindow;
float *win1 = win0 + 64 + 63;
float *win0_prev = (float*)swindow_prev;
float *win1_prev = win0_prev + 64 + 63;
float *src0_prev = saved + 448;
float *src1_prev = buf + 0*128 + 63;
float *src0 = buf + 0*128 + 64;
float *src1 = buf + 1*128 + 63;
for(i = 0; i < 64; i++)
{
temp0 = src0_prev[0];
temp1 = src1_prev[0];
wi = *win0_prev;
wj = *win1_prev;
temp2 = src0[0];
temp3 = src1[0];
dst0[0] = temp0 * wj - temp1 * wi;
dst1[0] = temp0 * wi + temp1 * wj;
wi = *win0;
wj = *win1;
temp0 = src0[128];
temp1 = src1[128];
dst0[128] = temp2 * wj - temp3 * wi;
dst1[128] = temp2 * wi + temp3 * wj;
temp2 = src0[256];
temp3 = src1[256];
dst0[256] = temp0 * wj - temp1 * wi;
dst1[256] = temp0 * wi + temp1 * wj;
dst0[384] = temp2 * wj - temp3 * wi;
dst1[384] = temp2 * wi + temp3 * wj;
temp0 = src0[384];
temp1 = src1[384];
dst0[512] = temp0 * wj - temp1 * wi;
dst2[0] = temp0 * wi + temp1 * wj;
src0++;
src1--;
src0_prev++;
src1_prev--;
win0++;
win1--;
win0_prev++;
win1_prev--;
dst0++;
dst1--;
dst2--;
}
}
} else {
ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
float_copy(out + 576, buf + 64, 448);
}
}
// buffer update
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
float_copy(saved + 448, buf + 7*128 + 64, 64);
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
float_copy(saved, buf + 512, 448);
float_copy(saved + 448, buf + 7*128 + 64, 64);
} else { // LONG_STOP or ONLY_LONG
float_copy(saved, buf + 512, 512);
}
}
static void apply_ltp_mips(AACContext *ac, SingleChannelElement *sce)
{
const LongTermPrediction *ltp = &sce->ics.ltp;
const uint16_t *offsets = sce->ics.swb_offset;
int i, sfb;
int j, k;
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
float *predTime = sce->ret;
float *predFreq = ac->buf_mdct;
float *p_predTime;
int16_t num_samples = 2048;
if (ltp->lag < 1024)
num_samples = ltp->lag + 1024;
j = (2048 - num_samples) >> 2;
k = (2048 - num_samples) & 3;
p_predTime = &predTime[num_samples];
for (i = 0; i < num_samples; i++)
predTime[i] = sce->ltp_state[i + 2048 - ltp->lag] * ltp->coef;
for (i = 0; i < j; i++) {
/* loop unrolled 4 times */
__asm__ volatile (
"sw $0, 0(%[p_predTime]) \n\t"
"sw $0, 4(%[p_predTime]) \n\t"
"sw $0, 8(%[p_predTime]) \n\t"
"sw $0, 12(%[p_predTime]) \n\t"
PTR_ADDIU "%[p_predTime], %[p_predTime], 16 \n\t"
: [p_predTime]"+r"(p_predTime)
:
: "memory"
);
}
for (i = 0; i < k; i++) {
__asm__ volatile (
"sw $0, 0(%[p_predTime]) \n\t"
PTR_ADDIU "%[p_predTime], %[p_predTime], 4 \n\t"
: [p_predTime]"+r"(p_predTime)
:
: "memory"
);
}
ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
if (sce->tns.present)
ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
if (ltp->used[sfb])
for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
sce->coeffs[i] += predFreq[i];
}
}
static av_always_inline void fmul_and_reverse(float *dst, const float *src0, const float *src1, int count)
{
/* Multiply 'count' floats in src0 by src1 and store the results in dst in reverse */
/* This should be equivalent to a normal fmul, followed by reversing dst */
// count must be a multiple of 4
av_assert2(count % 4 == 0);
// move src0 and src1 to the last element of their arrays
src0 += count - 1;
src1 += count - 1;
for (; count > 0; count -= 4){
float temp[12];
/* loop unrolled 4 times */
__asm__ volatile (
"lwc1 %[temp0], 0(%[ptr2]) \n\t"
"lwc1 %[temp1], -4(%[ptr2]) \n\t"
"lwc1 %[temp2], -8(%[ptr2]) \n\t"
"lwc1 %[temp3], -12(%[ptr2]) \n\t"
"lwc1 %[temp4], 0(%[ptr3]) \n\t"
"lwc1 %[temp5], -4(%[ptr3]) \n\t"
"lwc1 %[temp6], -8(%[ptr3]) \n\t"
"lwc1 %[temp7], -12(%[ptr3]) \n\t"
"mul.s %[temp8], %[temp0], %[temp4] \n\t"
"mul.s %[temp9], %[temp1], %[temp5] \n\t"
"mul.s %[temp10], %[temp2], %[temp6] \n\t"
"mul.s %[temp11], %[temp3], %[temp7] \n\t"
"swc1 %[temp8], 0(%[ptr1]) \n\t"
"swc1 %[temp9], 4(%[ptr1]) \n\t"
"swc1 %[temp10], 8(%[ptr1]) \n\t"
"swc1 %[temp11], 12(%[ptr1]) \n\t"
PTR_ADDIU "%[ptr1], %[ptr1], 16 \n\t"
PTR_ADDIU "%[ptr2], %[ptr2], -16 \n\t"
PTR_ADDIU "%[ptr3], %[ptr3], -16 \n\t"
: [temp0]"=&f"(temp[0]), [temp1]"=&f"(temp[1]),
[temp2]"=&f"(temp[2]), [temp3]"=&f"(temp[3]),
[temp4]"=&f"(temp[4]), [temp5]"=&f"(temp[5]),
[temp6]"=&f"(temp[6]), [temp7]"=&f"(temp[7]),
[temp8]"=&f"(temp[8]), [temp9]"=&f"(temp[9]),
[temp10]"=&f"(temp[10]), [temp11]"=&f"(temp[11]),
[ptr1]"+r"(dst), [ptr2]"+r"(src0), [ptr3]"+r"(src1)
:
: "memory"
);
}
}
static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce)
{
IndividualChannelStream *ics = &sce->ics;
float *saved = sce->saved;
float *saved_ltp = sce->coeffs;
const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
float *p_saved_ltp = saved_ltp + 576;
float *loop_end1 = p_saved_ltp + 448;
float_copy(saved_ltp, saved, 512);
/* loop unrolled 8 times */
__asm__ volatile (
"1: \n\t"
"sw $0, 0(%[p_saved_ltp]) \n\t"
"sw $0, 4(%[p_saved_ltp]) \n\t"
"sw $0, 8(%[p_saved_ltp]) \n\t"
"sw $0, 12(%[p_saved_ltp]) \n\t"
"sw $0, 16(%[p_saved_ltp]) \n\t"
"sw $0, 20(%[p_saved_ltp]) \n\t"
"sw $0, 24(%[p_saved_ltp]) \n\t"
"sw $0, 28(%[p_saved_ltp]) \n\t"
PTR_ADDIU "%[p_saved_ltp],%[p_saved_ltp], 32 \n\t"
"bne %[p_saved_ltp], %[loop_end1], 1b \n\t"
: [p_saved_ltp]"+r"(p_saved_ltp)
: [loop_end1]"r"(loop_end1)
: "memory"
);
ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 960, swindow, 64);
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
float *buff0 = saved;
float *buff1 = saved_ltp;
float *loop_end = saved + 448;
/* loop unrolled 8 times */
__asm__ volatile (
".set push \n\t"
".set noreorder \n\t"
"1: \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"
"lw %[temp4], 16(%[src]) \n\t"
"lw %[temp5], 20(%[src]) \n\t"
"lw %[temp6], 24(%[src]) \n\t"
"lw %[temp7], 28(%[src]) \n\t"
PTR_ADDIU "%[src], %[src], 32 \n\t"
"sw %[temp0], 0(%[dst]) \n\t"
"sw %[temp1], 4(%[dst]) \n\t"
"sw %[temp2], 8(%[dst]) \n\t"
"sw %[temp3], 12(%[dst]) \n\t"
"sw %[temp4], 16(%[dst]) \n\t"
"sw %[temp5], 20(%[dst]) \n\t"
"sw %[temp6], 24(%[dst]) \n\t"
"sw %[temp7], 28(%[dst]) \n\t"
"sw $0, 2304(%[dst]) \n\t"
"sw $0, 2308(%[dst]) \n\t"
"sw $0, 2312(%[dst]) \n\t"
"sw $0, 2316(%[dst]) \n\t"
"sw $0, 2320(%[dst]) \n\t"
"sw $0, 2324(%[dst]) \n\t"
"sw $0, 2328(%[dst]) \n\t"
"sw $0, 2332(%[dst]) \n\t"
"bne %[src], %[loop_end], 1b \n\t"
PTR_ADDIU "%[dst], %[dst], 32 \n\t"
".set pop \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
[src]"+r"(buff0), [dst]"+r"(buff1)
: [loop_end]"r"(loop_end)
: "memory"
);
ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 960, swindow, 64);
} else { // LONG_STOP or ONLY_LONG
ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
fmul_and_reverse(saved_ltp + 512, ac->buf_mdct + 512, lwindow, 512);
}
float_copy(sce->ltp_state, sce->ltp_state + 1024, 1024);
float_copy(sce->ltp_state + 1024, sce->ret, 1024);
float_copy(sce->ltp_state + 2048, saved_ltp, 1024);
}
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
void ff_aacdec_init_mips(AACContext *c)
{
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
c->imdct_and_windowing = imdct_and_windowing_mips;
c->apply_ltp = apply_ltp_mips;
c->update_ltp = update_ltp_mips;
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
}

253
externals/ffmpeg/libavcodec/mips/aacdec_mips.h vendored Executable file
View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Darko Laus (darko@mips.com)
* Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* AAC Spectral Band Replication decoding functions optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacdec.c
*/
#ifndef AVCODEC_MIPS_AACDEC_MIPS_H
#define AVCODEC_MIPS_AACDEC_MIPS_H
#include "libavcodec/aac.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM && HAVE_MIPSFPU
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static inline float *VMUL2_mips(float *dst, const float *v, unsigned idx,
const float *scale)
{
float temp0, temp1, temp2;
int temp3, temp4;
float *ret;
__asm__ volatile(
"andi %[temp3], %[idx], 0x0F \n\t"
"andi %[temp4], %[idx], 0xF0 \n\t"
"sll %[temp3], %[temp3], 2 \n\t"
"srl %[temp4], %[temp4], 2 \n\t"
"lwc1 %[temp2], 0(%[scale]) \n\t"
"lwxc1 %[temp0], %[temp3](%[v]) \n\t"
"lwxc1 %[temp1], %[temp4](%[v]) \n\t"
"mul.s %[temp0], %[temp0], %[temp2] \n\t"
"mul.s %[temp1], %[temp1], %[temp2] \n\t"
PTR_ADDIU "%[ret], %[dst], 8 \n\t"
"swc1 %[temp0], 0(%[dst]) \n\t"
"swc1 %[temp1], 4(%[dst]) \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
[temp2]"=&f"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [ret]"=&r"(ret)
: [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
[dst]"r"(dst)
: "memory"
);
return ret;
}
static inline float *VMUL4_mips(float *dst, const float *v, unsigned idx,
const float *scale)
{
int temp0, temp1, temp2, temp3;
float temp4, temp5, temp6, temp7, temp8;
float *ret;
__asm__ volatile(
"andi %[temp0], %[idx], 0x03 \n\t"
"andi %[temp1], %[idx], 0x0C \n\t"
"andi %[temp2], %[idx], 0x30 \n\t"
"andi %[temp3], %[idx], 0xC0 \n\t"
"sll %[temp0], %[temp0], 2 \n\t"
"srl %[temp2], %[temp2], 2 \n\t"
"srl %[temp3], %[temp3], 4 \n\t"
"lwc1 %[temp4], 0(%[scale]) \n\t"
"lwxc1 %[temp5], %[temp0](%[v]) \n\t"
"lwxc1 %[temp6], %[temp1](%[v]) \n\t"
"lwxc1 %[temp7], %[temp2](%[v]) \n\t"
"lwxc1 %[temp8], %[temp3](%[v]) \n\t"
"mul.s %[temp5], %[temp5], %[temp4] \n\t"
"mul.s %[temp6], %[temp6], %[temp4] \n\t"
"mul.s %[temp7], %[temp7], %[temp4] \n\t"
"mul.s %[temp8], %[temp8], %[temp4] \n\t"
PTR_ADDIU "%[ret], %[dst], 16 \n\t"
"swc1 %[temp5], 0(%[dst]) \n\t"
"swc1 %[temp6], 4(%[dst]) \n\t"
"swc1 %[temp7], 8(%[dst]) \n\t"
"swc1 %[temp8], 12(%[dst]) \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
[temp8]"=&f"(temp8), [ret]"=&r"(ret)
: [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
[dst]"r"(dst)
: "memory"
);
return ret;
}
static inline float *VMUL2S_mips(float *dst, const float *v, unsigned idx,
unsigned sign, const float *scale)
{
int temp0, temp1, temp2, temp3, temp4, temp5;
float temp6, temp7, temp8, temp9;
float *ret;
__asm__ volatile(
"andi %[temp0], %[idx], 0x0F \n\t"
"andi %[temp1], %[idx], 0xF0 \n\t"
"lw %[temp4], 0(%[scale]) \n\t"
"srl %[temp2], %[sign], 1 \n\t"
"sll %[temp3], %[sign], 31 \n\t"
"sll %[temp2], %[temp2], 31 \n\t"
"sll %[temp0], %[temp0], 2 \n\t"
"srl %[temp1], %[temp1], 2 \n\t"
"lwxc1 %[temp8], %[temp0](%[v]) \n\t"
"lwxc1 %[temp9], %[temp1](%[v]) \n\t"
"xor %[temp5], %[temp4], %[temp2] \n\t"
"xor %[temp4], %[temp4], %[temp3] \n\t"
"mtc1 %[temp5], %[temp6] \n\t"
"mtc1 %[temp4], %[temp7] \n\t"
"mul.s %[temp8], %[temp8], %[temp6] \n\t"
"mul.s %[temp9], %[temp9], %[temp7] \n\t"
PTR_ADDIU "%[ret], %[dst], 8 \n\t"
"swc1 %[temp8], 0(%[dst]) \n\t"
"swc1 %[temp9], 4(%[dst]) \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
[temp8]"=&f"(temp8), [temp9]"=&f"(temp9),
[ret]"=&r"(ret)
: [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
[dst]"r"(dst), [sign]"r"(sign)
: "memory"
);
return ret;
}
static inline float *VMUL4S_mips(float *dst, const float *v, unsigned idx,
unsigned sign, const float *scale)
{
int temp0, temp1, temp2, temp3, temp4;
float temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17;
float *ret;
unsigned int mask = 1U << 31;
__asm__ volatile(
"lw %[temp0], 0(%[scale]) \n\t"
"andi %[temp1], %[idx], 0x03 \n\t"
"andi %[temp2], %[idx], 0x0C \n\t"
"andi %[temp3], %[idx], 0x30 \n\t"
"andi %[temp4], %[idx], 0xC0 \n\t"
"sll %[temp1], %[temp1], 2 \n\t"
"srl %[temp3], %[temp3], 2 \n\t"
"srl %[temp4], %[temp4], 4 \n\t"
"lwxc1 %[temp10], %[temp1](%[v]) \n\t"
"lwxc1 %[temp11], %[temp2](%[v]) \n\t"
"lwxc1 %[temp12], %[temp3](%[v]) \n\t"
"lwxc1 %[temp13], %[temp4](%[v]) \n\t"
"and %[temp1], %[sign], %[mask] \n\t"
"srl %[temp2], %[idx], 12 \n\t"
"srl %[temp3], %[idx], 13 \n\t"
"srl %[temp4], %[idx], 14 \n\t"
"andi %[temp2], %[temp2], 1 \n\t"
"andi %[temp3], %[temp3], 1 \n\t"
"andi %[temp4], %[temp4], 1 \n\t"
"sllv %[sign], %[sign], %[temp2] \n\t"
"xor %[temp1], %[temp0], %[temp1] \n\t"
"and %[temp2], %[sign], %[mask] \n\t"
"mtc1 %[temp1], %[temp14] \n\t"
"xor %[temp2], %[temp0], %[temp2] \n\t"
"sllv %[sign], %[sign], %[temp3] \n\t"
"mtc1 %[temp2], %[temp15] \n\t"
"and %[temp3], %[sign], %[mask] \n\t"
"sllv %[sign], %[sign], %[temp4] \n\t"
"xor %[temp3], %[temp0], %[temp3] \n\t"
"and %[temp4], %[sign], %[mask] \n\t"
"mtc1 %[temp3], %[temp16] \n\t"
"xor %[temp4], %[temp0], %[temp4] \n\t"
"mtc1 %[temp4], %[temp17] \n\t"
"mul.s %[temp10], %[temp10], %[temp14] \n\t"
"mul.s %[temp11], %[temp11], %[temp15] \n\t"
"mul.s %[temp12], %[temp12], %[temp16] \n\t"
"mul.s %[temp13], %[temp13], %[temp17] \n\t"
PTR_ADDIU "%[ret], %[dst], 16 \n\t"
"swc1 %[temp10], 0(%[dst]) \n\t"
"swc1 %[temp11], 4(%[dst]) \n\t"
"swc1 %[temp12], 8(%[dst]) \n\t"
"swc1 %[temp13], 12(%[dst]) \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp10]"=&f"(temp10),
[temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
[temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
[temp15]"=&f"(temp15), [temp16]"=&f"(temp16),
[temp17]"=&f"(temp17), [ret]"=&r"(ret),
[sign]"+r"(sign)
: [idx]"r"(idx), [scale]"r"(scale), [v]"r"(v),
[dst]"r"(dst), [mask]"r"(mask)
: "memory"
);
return ret;
}
#define VMUL2 VMUL2_mips
#define VMUL4 VMUL4_mips
#define VMUL2S VMUL2S_mips
#define VMUL4S VMUL4S_mips
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
#endif /* AVCODEC_MIPS_AACDEC_MIPS_H */

View File

@@ -0,0 +1,464 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Darko Laus (darko@mips.com)
* Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacpsdsp.c
*/
#include "config.h"
#include "libavcodec/aacpsdsp.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
static void ps_hybrid_analysis_ileave_mips(float (*out)[32][2], float L[2][38][64],
int i, int len)
{
int temp0, temp1, temp2, temp3;
int temp4, temp5, temp6, temp7;
float *out1=&out[i][0][0];
float *L1=&L[0][0][i];
float *j=out1+ len*2;
for (; i < 64; i++) {
/* loop unrolled 8 times */
__asm__ volatile (
"1: \n\t"
"lw %[temp0], 0(%[L1]) \n\t"
"lw %[temp1], 9728(%[L1]) \n\t"
"lw %[temp2], 256(%[L1]) \n\t"
"lw %[temp3], 9984(%[L1]) \n\t"
"lw %[temp4], 512(%[L1]) \n\t"
"lw %[temp5], 10240(%[L1]) \n\t"
"lw %[temp6], 768(%[L1]) \n\t"
"lw %[temp7], 10496(%[L1]) \n\t"
"sw %[temp0], 0(%[out1]) \n\t"
"sw %[temp1], 4(%[out1]) \n\t"
"sw %[temp2], 8(%[out1]) \n\t"
"sw %[temp3], 12(%[out1]) \n\t"
"sw %[temp4], 16(%[out1]) \n\t"
"sw %[temp5], 20(%[out1]) \n\t"
"sw %[temp6], 24(%[out1]) \n\t"
"sw %[temp7], 28(%[out1]) \n\t"
PTR_ADDIU "%[out1], %[out1], 32 \n\t"
PTR_ADDIU "%[L1], %[L1], 1024 \n\t"
"bne %[out1], %[j], 1b \n\t"
: [out1]"+r"(out1), [L1]"+r"(L1), [j]"+r"(j),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
: [len]"r"(len)
: "memory"
);
out1-=(len<<1)-64;
L1-=(len<<6)-1;
j+=len*2;
}
}
static void ps_hybrid_synthesis_deint_mips(float out[2][38][64],
float (*in)[32][2],
int i, int len)
{
int n;
int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
float *out1 = (float*)out + i;
float *out2 = (float*)out + 2432 + i;
float *in1 = (float*)in + 64 * i;
float *in2 = (float*)in + 64 * i + 1;
for (; i < 64; i++) {
for (n = 0; n < 7; n++) {
/* loop unrolled 8 times */
__asm__ volatile (
"lw %[temp0], 0(%[in1]) \n\t"
"lw %[temp1], 0(%[in2]) \n\t"
"lw %[temp2], 8(%[in1]) \n\t"
"lw %[temp3], 8(%[in2]) \n\t"
"lw %[temp4], 16(%[in1]) \n\t"
"lw %[temp5], 16(%[in2]) \n\t"
"lw %[temp6], 24(%[in1]) \n\t"
"lw %[temp7], 24(%[in2]) \n\t"
PTR_ADDIU "%[out1], %[out1], 1024 \n\t"
PTR_ADDIU "%[out2], %[out2], 1024 \n\t"
PTR_ADDIU "%[in1], %[in1], 32 \n\t"
PTR_ADDIU "%[in2], %[in2], 32 \n\t"
"sw %[temp0], -1024(%[out1]) \n\t"
"sw %[temp1], -1024(%[out2]) \n\t"
"sw %[temp2], -768(%[out1]) \n\t"
"sw %[temp3], -768(%[out2]) \n\t"
"sw %[temp4], -512(%[out1]) \n\t"
"sw %[temp5], -512(%[out2]) \n\t"
"sw %[temp6], -256(%[out1]) \n\t"
"sw %[temp7], -256(%[out2]) \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
[out1]"+r"(out1), [out2]"+r"(out2),
[in1]"+r"(in1), [in2]"+r"(in2)
:
: "memory"
);
}
/* loop unrolled 8 times */
__asm__ volatile (
"lw %[temp0], 0(%[in1]) \n\t"
"lw %[temp1], 0(%[in2]) \n\t"
"lw %[temp2], 8(%[in1]) \n\t"
"lw %[temp3], 8(%[in2]) \n\t"
"lw %[temp4], 16(%[in1]) \n\t"
"lw %[temp5], 16(%[in2]) \n\t"
"lw %[temp6], 24(%[in1]) \n\t"
"lw %[temp7], 24(%[in2]) \n\t"
PTR_ADDIU "%[out1], %[out1], -7164 \n\t"
PTR_ADDIU "%[out2], %[out2], -7164 \n\t"
PTR_ADDIU "%[in1], %[in1], 32 \n\t"
PTR_ADDIU "%[in2], %[in2], 32 \n\t"
"sw %[temp0], 7164(%[out1]) \n\t"
"sw %[temp1], 7164(%[out2]) \n\t"
"sw %[temp2], 7420(%[out1]) \n\t"
"sw %[temp3], 7420(%[out2]) \n\t"
"sw %[temp4], 7676(%[out1]) \n\t"
"sw %[temp5], 7676(%[out2]) \n\t"
"sw %[temp6], 7932(%[out1]) \n\t"
"sw %[temp7], 7932(%[out2]) \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7),
[out1]"+r"(out1), [out2]"+r"(out2),
[in1]"+r"(in1), [in2]"+r"(in2)
:
: "memory"
);
}
}
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ps_add_squares_mips(float *dst, const float (*src)[2], int n)
{
int i;
float temp0, temp1, temp2, temp3, temp4, temp5;
float temp6, temp7, temp8, temp9, temp10, temp11;
float *src0 = (float*)&src[0][0];
float *dst0 = &dst[0];
for (i = 0; i < 8; i++) {
/* loop unrolled 4 times */
__asm__ volatile (
"lwc1 %[temp0], 0(%[src0]) \n\t"
"lwc1 %[temp1], 4(%[src0]) \n\t"
"lwc1 %[temp2], 8(%[src0]) \n\t"
"lwc1 %[temp3], 12(%[src0]) \n\t"
"lwc1 %[temp4], 16(%[src0]) \n\t"
"lwc1 %[temp5], 20(%[src0]) \n\t"
"lwc1 %[temp6], 24(%[src0]) \n\t"
"lwc1 %[temp7], 28(%[src0]) \n\t"
"lwc1 %[temp8], 0(%[dst0]) \n\t"
"lwc1 %[temp9], 4(%[dst0]) \n\t"
"lwc1 %[temp10], 8(%[dst0]) \n\t"
"lwc1 %[temp11], 12(%[dst0]) \n\t"
"mul.s %[temp1], %[temp1], %[temp1] \n\t"
"mul.s %[temp3], %[temp3], %[temp3] \n\t"
"mul.s %[temp5], %[temp5], %[temp5] \n\t"
"mul.s %[temp7], %[temp7], %[temp7] \n\t"
"madd.s %[temp0], %[temp1], %[temp0], %[temp0] \n\t"
"madd.s %[temp2], %[temp3], %[temp2], %[temp2] \n\t"
"madd.s %[temp4], %[temp5], %[temp4], %[temp4] \n\t"
"madd.s %[temp6], %[temp7], %[temp6], %[temp6] \n\t"
"add.s %[temp0], %[temp8], %[temp0] \n\t"
"add.s %[temp2], %[temp9], %[temp2] \n\t"
"add.s %[temp4], %[temp10], %[temp4] \n\t"
"add.s %[temp6], %[temp11], %[temp6] \n\t"
"swc1 %[temp0], 0(%[dst0]) \n\t"
"swc1 %[temp2], 4(%[dst0]) \n\t"
"swc1 %[temp4], 8(%[dst0]) \n\t"
"swc1 %[temp6], 12(%[dst0]) \n\t"
PTR_ADDIU "%[dst0], %[dst0], 16 \n\t"
PTR_ADDIU "%[src0], %[src0], 32 \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [dst0]"+r"(dst0), [src0]"+r"(src0),
[temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
:
: "memory"
);
}
}
static void ps_mul_pair_single_mips(float (*dst)[2], float (*src0)[2], float *src1,
int n)
{
float temp0, temp1, temp2;
float *p_d, *p_s0, *p_s1, *end;
p_d = &dst[0][0];
p_s0 = &src0[0][0];
p_s1 = &src1[0];
end = p_s1 + n;
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"1: \n\t"
"lwc1 %[temp2], 0(%[p_s1]) \n\t"
"lwc1 %[temp0], 0(%[p_s0]) \n\t"
"lwc1 %[temp1], 4(%[p_s0]) \n\t"
PTR_ADDIU "%[p_d], %[p_d], 8 \n\t"
"mul.s %[temp0], %[temp0], %[temp2] \n\t"
"mul.s %[temp1], %[temp1], %[temp2] \n\t"
PTR_ADDIU "%[p_s0], %[p_s0], 8 \n\t"
"swc1 %[temp0], -8(%[p_d]) \n\t"
"swc1 %[temp1], -4(%[p_d]) \n\t"
"bne %[p_s1], %[end], 1b \n\t"
PTR_ADDIU "%[p_s1], %[p_s1], 4 \n\t"
".set pop \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
[temp2]"=&f"(temp2), [p_d]"+r"(p_d),
[p_s0]"+r"(p_s0), [p_s1]"+r"(p_s1)
: [end]"r"(end)
: "memory"
);
}
static void ps_decorrelate_mips(float (*out)[2], float (*delay)[2],
float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
const float phi_fract[2], const float (*Q_fract)[2],
const float *transient_gain,
float g_decay_slope,
int len)
{
float *p_delay = &delay[0][0];
float *p_out = &out[0][0];
float *p_ap_delay = &ap_delay[0][0][0];
const float *p_t_gain = transient_gain;
const float *p_Q_fract = &Q_fract[0][0];
float ag0, ag1, ag2;
float phi_fract0 = phi_fract[0];
float phi_fract1 = phi_fract[1];
float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
float *p_delay_end = (p_delay + (len << 1));
/* merged 2 loops */
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"li.s %[ag0], 0.65143905753106 \n\t"
"li.s %[ag1], 0.56471812200776 \n\t"
"li.s %[ag2], 0.48954165955695 \n\t"
"mul.s %[ag0], %[ag0], %[g_decay_slope] \n\t"
"mul.s %[ag1], %[ag1], %[g_decay_slope] \n\t"
"mul.s %[ag2], %[ag2], %[g_decay_slope] \n\t"
"1: \n\t"
"lwc1 %[temp0], 0(%[p_delay]) \n\t"
"lwc1 %[temp1], 4(%[p_delay]) \n\t"
"lwc1 %[temp4], 16(%[p_ap_delay]) \n\t"
"lwc1 %[temp5], 20(%[p_ap_delay]) \n\t"
"mul.s %[temp3], %[temp0], %[phi_fract1] \n\t"
"lwc1 %[temp6], 0(%[p_Q_fract]) \n\t"
"mul.s %[temp2], %[temp1], %[phi_fract1] \n\t"
"lwc1 %[temp7], 4(%[p_Q_fract]) \n\t"
"madd.s %[temp3], %[temp3], %[temp1], %[phi_fract0] \n\t"
"msub.s %[temp2], %[temp2], %[temp0], %[phi_fract0] \n\t"
"mul.s %[temp8], %[temp5], %[temp7] \n\t"
"mul.s %[temp9], %[temp4], %[temp7] \n\t"
"lwc1 %[temp7], 12(%[p_Q_fract]) \n\t"
"mul.s %[temp0], %[ag0], %[temp2] \n\t"
"mul.s %[temp1], %[ag0], %[temp3] \n\t"
"msub.s %[temp8], %[temp8], %[temp4], %[temp6] \n\t"
"lwc1 %[temp4], 304(%[p_ap_delay]) \n\t"
"madd.s %[temp9], %[temp9], %[temp5], %[temp6] \n\t"
"lwc1 %[temp5], 308(%[p_ap_delay]) \n\t"
"sub.s %[temp0], %[temp8], %[temp0] \n\t"
"sub.s %[temp1], %[temp9], %[temp1] \n\t"
"madd.s %[temp2], %[temp2], %[ag0], %[temp0] \n\t"
"lwc1 %[temp6], 8(%[p_Q_fract]) \n\t"
"madd.s %[temp3], %[temp3], %[ag0], %[temp1] \n\t"
"mul.s %[temp8], %[temp5], %[temp7] \n\t"
"mul.s %[temp9], %[temp4], %[temp7] \n\t"
"lwc1 %[temp7], 20(%[p_Q_fract]) \n\t"
"msub.s %[temp8], %[temp8], %[temp4], %[temp6] \n\t"
"swc1 %[temp2], 40(%[p_ap_delay]) \n\t"
"mul.s %[temp2], %[ag1], %[temp0] \n\t"
"swc1 %[temp3], 44(%[p_ap_delay]) \n\t"
"mul.s %[temp3], %[ag1], %[temp1] \n\t"
"lwc1 %[temp4], 592(%[p_ap_delay]) \n\t"
"madd.s %[temp9], %[temp9], %[temp5], %[temp6] \n\t"
"lwc1 %[temp5], 596(%[p_ap_delay]) \n\t"
"sub.s %[temp2], %[temp8], %[temp2] \n\t"
"sub.s %[temp3], %[temp9], %[temp3] \n\t"
"lwc1 %[temp6], 16(%[p_Q_fract]) \n\t"
"madd.s %[temp0], %[temp0], %[ag1], %[temp2] \n\t"
"madd.s %[temp1], %[temp1], %[ag1], %[temp3] \n\t"
"mul.s %[temp8], %[temp5], %[temp7] \n\t"
"mul.s %[temp9], %[temp4], %[temp7] \n\t"
"msub.s %[temp8], %[temp8], %[temp4], %[temp6] \n\t"
"madd.s %[temp9], %[temp9], %[temp5], %[temp6] \n\t"
"swc1 %[temp0], 336(%[p_ap_delay]) \n\t"
"mul.s %[temp0], %[ag2], %[temp2] \n\t"
"swc1 %[temp1], 340(%[p_ap_delay]) \n\t"
"mul.s %[temp1], %[ag2], %[temp3] \n\t"
"lwc1 %[temp4], 0(%[p_t_gain]) \n\t"
"sub.s %[temp0], %[temp8], %[temp0] \n\t"
PTR_ADDIU "%[p_ap_delay], %[p_ap_delay], 8 \n\t"
"sub.s %[temp1], %[temp9], %[temp1] \n\t"
PTR_ADDIU "%[p_t_gain], %[p_t_gain], 4 \n\t"
"madd.s %[temp2], %[temp2], %[ag2], %[temp0] \n\t"
PTR_ADDIU "%[p_delay], %[p_delay], 8 \n\t"
"madd.s %[temp3], %[temp3], %[ag2], %[temp1] \n\t"
PTR_ADDIU "%[p_out], %[p_out], 8 \n\t"
"mul.s %[temp5], %[temp4], %[temp0] \n\t"
"mul.s %[temp6], %[temp4], %[temp1] \n\t"
"swc1 %[temp2], 624(%[p_ap_delay]) \n\t"
"swc1 %[temp3], 628(%[p_ap_delay]) \n\t"
"swc1 %[temp5], -8(%[p_out]) \n\t"
"swc1 %[temp6], -4(%[p_out]) \n\t"
"bne %[p_delay], %[p_delay_end],1b \n\t"
" swc1 %[temp6], -4(%[p_out]) \n\t"
".set pop \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [p_delay]"+r"(p_delay), [p_ap_delay]"+r"(p_ap_delay),
[p_Q_fract]"+r"(p_Q_fract), [p_t_gain]"+r"(p_t_gain), [p_out]"+r"(p_out),
[ag0]"=&f"(ag0), [ag1]"=&f"(ag1), [ag2]"=&f"(ag2)
: [phi_fract0]"f"(phi_fract0), [phi_fract1]"f"(phi_fract1),
[p_delay_end]"r"(p_delay_end), [g_decay_slope]"f"(g_decay_slope)
: "memory"
);
}
static void ps_stereo_interpolate_mips(float (*l)[2], float (*r)[2],
float h[2][4], float h_step[2][4],
int len)
{
float h0 = h[0][0];
float h1 = h[0][1];
float h2 = h[0][2];
float h3 = h[0][3];
float hs0 = h_step[0][0];
float hs1 = h_step[0][1];
float hs2 = h_step[0][2];
float hs3 = h_step[0][3];
float temp0, temp1, temp2, temp3;
float l_re, l_im, r_re, r_im;
float *l_end = ((float *)l + (len << 1));
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"1: \n\t"
"add.s %[h0], %[h0], %[hs0] \n\t"
"lwc1 %[l_re], 0(%[l]) \n\t"
"add.s %[h1], %[h1], %[hs1] \n\t"
"lwc1 %[r_re], 0(%[r]) \n\t"
"add.s %[h2], %[h2], %[hs2] \n\t"
"lwc1 %[l_im], 4(%[l]) \n\t"
"add.s %[h3], %[h3], %[hs3] \n\t"
"lwc1 %[r_im], 4(%[r]) \n\t"
"mul.s %[temp0], %[h0], %[l_re] \n\t"
PTR_ADDIU "%[l], %[l], 8 \n\t"
"mul.s %[temp2], %[h1], %[l_re] \n\t"
PTR_ADDIU "%[r], %[r], 8 \n\t"
"madd.s %[temp0], %[temp0], %[h2], %[r_re] \n\t"
"madd.s %[temp2], %[temp2], %[h3], %[r_re] \n\t"
"mul.s %[temp1], %[h0], %[l_im] \n\t"
"mul.s %[temp3], %[h1], %[l_im] \n\t"
"madd.s %[temp1], %[temp1], %[h2], %[r_im] \n\t"
"madd.s %[temp3], %[temp3], %[h3], %[r_im] \n\t"
"swc1 %[temp0], -8(%[l]) \n\t"
"swc1 %[temp2], -8(%[r]) \n\t"
"swc1 %[temp1], -4(%[l]) \n\t"
"bne %[l], %[l_end], 1b \n\t"
" swc1 %[temp3], -4(%[r]) \n\t"
".set pop \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
[temp2]"=&f"(temp2), [temp3]"=&f"(temp3),
[h0]"+f"(h0), [h1]"+f"(h1), [h2]"+f"(h2),
[h3]"+f"(h3), [l]"+r"(l), [r]"+r"(r),
[l_re]"=&f"(l_re), [l_im]"=&f"(l_im),
[r_re]"=&f"(r_re), [r_im]"=&f"(r_im)
: [hs0]"f"(hs0), [hs1]"f"(hs1), [hs2]"f"(hs2),
[hs3]"f"(hs3), [l_end]"r"(l_end)
: "memory"
);
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
void ff_psdsp_init_mips(PSDSPContext *s)
{
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_mips;
s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_mips;
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
s->add_squares = ps_add_squares_mips;
s->mul_pair_single = ps_mul_pair_single_mips;
s->decorrelate = ps_decorrelate_mips;
s->stereo_interpolate[0] = ps_stereo_interpolate_mips;
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
}

238
externals/ffmpeg/libavcodec/mips/aacpsy_mips.h vendored Executable file
View File

@@ -0,0 +1,238 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Bojan Zivkovic (bojan@mips.com)
*
* AAC encoder psychoacoustic model routines optimized
* for MIPS floating-point architecture
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacpsy.c
*/
#ifndef AVCODEC_MIPS_AACPSY_MIPS_H
#define AVCODEC_MIPS_AACPSY_MIPS_H
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM && HAVE_MIPSFPU && ( PSY_LAME_FIR_LEN == 21 )
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void calc_thr_3gpp_mips(const FFPsyWindowInfo *wi, const int num_bands,
AacPsyChannel *pch, const uint8_t *band_sizes,
const float *coefs, const int cutoff)
{
int i, w, g;
int start = 0, wstart = 0;
for (w = 0; w < wi->num_windows*16; w += 16) {
wstart = 0;
for (g = 0; g < num_bands; g++) {
AacPsyBand *band = &pch->band[w+g];
float form_factor = 0.0f;
float Temp;
band->energy = 0.0f;
if (wstart < cutoff) {
for (i = 0; i < band_sizes[g]; i+=4) {
float a, b, c, d;
float ax, bx, cx, dx;
float *cf = (float *)&coefs[start+i];
__asm__ volatile (
"lwc1 %[a], 0(%[cf]) \n\t"
"lwc1 %[b], 4(%[cf]) \n\t"
"lwc1 %[c], 8(%[cf]) \n\t"
"lwc1 %[d], 12(%[cf]) \n\t"
"abs.s %[a], %[a] \n\t"
"abs.s %[b], %[b] \n\t"
"abs.s %[c], %[c] \n\t"
"abs.s %[d], %[d] \n\t"
"sqrt.s %[ax], %[a] \n\t"
"sqrt.s %[bx], %[b] \n\t"
"sqrt.s %[cx], %[c] \n\t"
"sqrt.s %[dx], %[d] \n\t"
"madd.s %[e], %[e], %[a], %[a] \n\t"
"madd.s %[e], %[e], %[b], %[b] \n\t"
"madd.s %[e], %[e], %[c], %[c] \n\t"
"madd.s %[e], %[e], %[d], %[d] \n\t"
"add.s %[f], %[f], %[ax] \n\t"
"add.s %[f], %[f], %[bx] \n\t"
"add.s %[f], %[f], %[cx] \n\t"
"add.s %[f], %[f], %[dx] \n\t"
: [a]"=&f"(a), [b]"=&f"(b),
[c]"=&f"(c), [d]"=&f"(d),
[e]"+f"(band->energy), [f]"+f"(form_factor),
[ax]"=&f"(ax), [bx]"=&f"(bx),
[cx]"=&f"(cx), [dx]"=&f"(dx)
: [cf]"r"(cf)
: "memory"
);
}
}
Temp = sqrtf((float)band_sizes[g] / band->energy);
band->thr = band->energy * 0.001258925f;
band->nz_lines = form_factor * sqrtf(Temp);
start += band_sizes[g];
wstart += band_sizes[g];
}
}
}
static void psy_hp_filter_mips(const float *firbuf, float *hpfsmpl, const float * psy_fir_coeffs)
{
float sum1, sum2, sum3, sum4;
float *fb = (float*)firbuf;
float *fb_end = fb + AAC_BLOCK_SIZE_LONG;
float *hp = hpfsmpl;
float coeff0 = psy_fir_coeffs[1];
float coeff1 = psy_fir_coeffs[3];
float coeff2 = psy_fir_coeffs[5];
float coeff3 = psy_fir_coeffs[7];
float coeff4 = psy_fir_coeffs[9];
__asm__ volatile (
".set push \n\t"
".set noreorder \n\t"
"li.s $f12, 32768 \n\t"
"1: \n\t"
"lwc1 $f0, 40(%[fb]) \n\t"
"lwc1 $f1, 4(%[fb]) \n\t"
"lwc1 $f2, 80(%[fb]) \n\t"
"lwc1 $f3, 44(%[fb]) \n\t"
"lwc1 $f4, 8(%[fb]) \n\t"
"madd.s %[sum1], $f0, $f1, %[coeff0] \n\t"
"lwc1 $f5, 84(%[fb]) \n\t"
"lwc1 $f6, 48(%[fb]) \n\t"
"madd.s %[sum2], $f3, $f4, %[coeff0] \n\t"
"lwc1 $f7, 12(%[fb]) \n\t"
"madd.s %[sum1], %[sum1], $f2, %[coeff0] \n\t"
"lwc1 $f8, 88(%[fb]) \n\t"
"lwc1 $f9, 52(%[fb]) \n\t"
"madd.s %[sum2], %[sum2], $f5, %[coeff0] \n\t"
"madd.s %[sum3], $f6, $f7, %[coeff0] \n\t"
"lwc1 $f10, 16(%[fb]) \n\t"
"lwc1 $f11, 92(%[fb]) \n\t"
"madd.s %[sum1], %[sum1], $f7, %[coeff1] \n\t"
"lwc1 $f1, 72(%[fb]) \n\t"
"madd.s %[sum3], %[sum3], $f8, %[coeff0] \n\t"
"madd.s %[sum4], $f9, $f10, %[coeff0] \n\t"
"madd.s %[sum2], %[sum2], $f10, %[coeff1] \n\t"
"madd.s %[sum1], %[sum1], $f1, %[coeff1] \n\t"
"lwc1 $f4, 76(%[fb]) \n\t"
"lwc1 $f8, 20(%[fb]) \n\t"
"madd.s %[sum4], %[sum4], $f11, %[coeff0] \n\t"
"lwc1 $f11, 24(%[fb]) \n\t"
"madd.s %[sum2], %[sum2], $f4, %[coeff1] \n\t"
"madd.s %[sum1], %[sum1], $f8, %[coeff2] \n\t"
"madd.s %[sum3], %[sum3], $f8, %[coeff1] \n\t"
"madd.s %[sum4], %[sum4], $f11, %[coeff1] \n\t"
"lwc1 $f7, 64(%[fb]) \n\t"
"madd.s %[sum2], %[sum2], $f11, %[coeff2] \n\t"
"lwc1 $f10, 68(%[fb]) \n\t"
"madd.s %[sum3], %[sum3], $f2, %[coeff1] \n\t"
"madd.s %[sum4], %[sum4], $f5, %[coeff1] \n\t"
"madd.s %[sum1], %[sum1], $f7, %[coeff2] \n\t"
"madd.s %[sum2], %[sum2], $f10, %[coeff2] \n\t"
"lwc1 $f2, 28(%[fb]) \n\t"
"lwc1 $f5, 32(%[fb]) \n\t"
"lwc1 $f8, 56(%[fb]) \n\t"
"lwc1 $f11, 60(%[fb]) \n\t"
"madd.s %[sum3], %[sum3], $f2, %[coeff2] \n\t"
"madd.s %[sum4], %[sum4], $f5, %[coeff2] \n\t"
"madd.s %[sum1], %[sum1], $f2, %[coeff3] \n\t"
"madd.s %[sum2], %[sum2], $f5, %[coeff3] \n\t"
"madd.s %[sum3], %[sum3], $f1, %[coeff2] \n\t"
"madd.s %[sum4], %[sum4], $f4, %[coeff2] \n\t"
"madd.s %[sum1], %[sum1], $f8, %[coeff3] \n\t"
"madd.s %[sum2], %[sum2], $f11, %[coeff3] \n\t"
"lwc1 $f1, 36(%[fb]) \n\t"
PTR_ADDIU "%[fb], %[fb], 16 \n\t"
"madd.s %[sum4], %[sum4], $f0, %[coeff3] \n\t"
"madd.s %[sum3], %[sum3], $f1, %[coeff3] \n\t"
"madd.s %[sum1], %[sum1], $f1, %[coeff4] \n\t"
"madd.s %[sum2], %[sum2], $f0, %[coeff4] \n\t"
"madd.s %[sum4], %[sum4], $f10, %[coeff3] \n\t"
"madd.s %[sum3], %[sum3], $f7, %[coeff3] \n\t"
"madd.s %[sum1], %[sum1], $f6, %[coeff4] \n\t"
"madd.s %[sum2], %[sum2], $f9, %[coeff4] \n\t"
"madd.s %[sum4], %[sum4], $f6, %[coeff4] \n\t"
"madd.s %[sum3], %[sum3], $f3, %[coeff4] \n\t"
"mul.s %[sum1], %[sum1], $f12 \n\t"
"mul.s %[sum2], %[sum2], $f12 \n\t"
"madd.s %[sum4], %[sum4], $f11, %[coeff4] \n\t"
"madd.s %[sum3], %[sum3], $f8, %[coeff4] \n\t"
"swc1 %[sum1], 0(%[hp]) \n\t"
"swc1 %[sum2], 4(%[hp]) \n\t"
"mul.s %[sum4], %[sum4], $f12 \n\t"
"mul.s %[sum3], %[sum3], $f12 \n\t"
"swc1 %[sum4], 12(%[hp]) \n\t"
"swc1 %[sum3], 8(%[hp]) \n\t"
"bne %[fb], %[fb_end], 1b \n\t"
PTR_ADDIU "%[hp], %[hp], 16 \n\t"
".set pop \n\t"
: [sum1]"=&f"(sum1), [sum2]"=&f"(sum2),
[sum3]"=&f"(sum3), [sum4]"=&f"(sum4),
[fb]"+r"(fb), [hp]"+r"(hp)
: [coeff0]"f"(coeff0), [coeff1]"f"(coeff1),
[coeff2]"f"(coeff2), [coeff3]"f"(coeff3),
[coeff4]"f"(coeff4), [fb_end]"r"(fb_end)
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6",
"$f7", "$f8", "$f9", "$f10", "$f11", "$f12",
"memory"
);
}
#define calc_thr_3gpp calc_thr_3gpp_mips
#define psy_hp_filter psy_hp_filter_mips
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM && HAVE_MIPSFPU */
#endif /* AVCODEC_MIPS_AACPSY_MIPS_H */

623
externals/ffmpeg/libavcodec/mips/aacsbr_mips.c vendored Executable file
View File

@@ -0,0 +1,623 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacsbr.c
*/
#include "libavcodec/aac.h"
#include "libavcodec/aacsbr.h"
#include "libavutil/mips/asmdefs.h"
#define ENVELOPE_ADJUSTMENT_OFFSET 2
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
static int sbr_lf_gen_mips(AACContext *ac, SpectralBandReplication *sbr,
float X_low[32][40][2], const float W[2][32][32][2],
int buf_idx)
{
int i, k;
int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
float *p_x_low = &X_low[0][8][0];
float *p_w = (float*)&W[buf_idx][0][0][0];
float *p_x1_low = &X_low[0][0][0];
float *p_w1 = (float*)&W[1-buf_idx][24][0][0];
float *loop_end=p_x1_low + 2560;
/* loop unrolled 8 times */
__asm__ volatile (
"1: \n\t"
"sw $0, 0(%[p_x1_low]) \n\t"
"sw $0, 4(%[p_x1_low]) \n\t"
"sw $0, 8(%[p_x1_low]) \n\t"
"sw $0, 12(%[p_x1_low]) \n\t"
"sw $0, 16(%[p_x1_low]) \n\t"
"sw $0, 20(%[p_x1_low]) \n\t"
"sw $0, 24(%[p_x1_low]) \n\t"
"sw $0, 28(%[p_x1_low]) \n\t"
PTR_ADDIU "%[p_x1_low],%[p_x1_low], 32 \n\t"
"bne %[p_x1_low], %[loop_end], 1b \n\t"
PTR_ADDIU "%[p_x1_low],%[p_x1_low], -10240 \n\t"
: [p_x1_low]"+r"(p_x1_low)
: [loop_end]"r"(loop_end)
: "memory"
);
for (k = 0; k < sbr->kx[1]; k++) {
for (i = 0; i < 32; i+=4) {
/* loop unrolled 4 times */
__asm__ volatile (
"lw %[temp0], 0(%[p_w]) \n\t"
"lw %[temp1], 4(%[p_w]) \n\t"
"lw %[temp2], 256(%[p_w]) \n\t"
"lw %[temp3], 260(%[p_w]) \n\t"
"lw %[temp4], 512(%[p_w]) \n\t"
"lw %[temp5], 516(%[p_w]) \n\t"
"lw %[temp6], 768(%[p_w]) \n\t"
"lw %[temp7], 772(%[p_w]) \n\t"
"sw %[temp0], 0(%[p_x_low]) \n\t"
"sw %[temp1], 4(%[p_x_low]) \n\t"
"sw %[temp2], 8(%[p_x_low]) \n\t"
"sw %[temp3], 12(%[p_x_low]) \n\t"
"sw %[temp4], 16(%[p_x_low]) \n\t"
"sw %[temp5], 20(%[p_x_low]) \n\t"
"sw %[temp6], 24(%[p_x_low]) \n\t"
"sw %[temp7], 28(%[p_x_low]) \n\t"
PTR_ADDIU "%[p_x_low], %[p_x_low], 32 \n\t"
PTR_ADDIU "%[p_w], %[p_w], 1024 \n\t"
: [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_w]"+r"(p_w), [p_x_low]"+r"(p_x_low)
:
: "memory"
);
}
p_x_low += 16;
p_w -= 2046;
}
for (k = 0; k < sbr->kx[0]; k++) {
for (i = 0; i < 2; i++) {
/* loop unrolled 4 times */
__asm__ volatile (
"lw %[temp0], 0(%[p_w1]) \n\t"
"lw %[temp1], 4(%[p_w1]) \n\t"
"lw %[temp2], 256(%[p_w1]) \n\t"
"lw %[temp3], 260(%[p_w1]) \n\t"
"lw %[temp4], 512(%[p_w1]) \n\t"
"lw %[temp5], 516(%[p_w1]) \n\t"
"lw %[temp6], 768(%[p_w1]) \n\t"
"lw %[temp7], 772(%[p_w1]) \n\t"
"sw %[temp0], 0(%[p_x1_low]) \n\t"
"sw %[temp1], 4(%[p_x1_low]) \n\t"
"sw %[temp2], 8(%[p_x1_low]) \n\t"
"sw %[temp3], 12(%[p_x1_low]) \n\t"
"sw %[temp4], 16(%[p_x1_low]) \n\t"
"sw %[temp5], 20(%[p_x1_low]) \n\t"
"sw %[temp6], 24(%[p_x1_low]) \n\t"
"sw %[temp7], 28(%[p_x1_low]) \n\t"
PTR_ADDIU "%[p_x1_low], %[p_x1_low], 32 \n\t"
PTR_ADDIU "%[p_w1], %[p_w1], 1024 \n\t"
: [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_w1]"+r"(p_w1), [p_x1_low]"+r"(p_x1_low)
:
: "memory"
);
}
p_x1_low += 64;
p_w1 -= 510;
}
return 0;
}
static int sbr_x_gen_mips(SpectralBandReplication *sbr, float X[2][38][64],
const float Y0[38][64][2], const float Y1[38][64][2],
const float X_low[32][40][2], int ch)
{
int k, i;
const int i_f = 32;
int temp0, temp1, temp2, temp3;
const float *X_low1, *Y01, *Y11;
float *x1=&X[0][0][0];
float *j=x1+4864;
const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
/* loop unrolled 8 times */
__asm__ volatile (
"1: \n\t"
"sw $0, 0(%[x1]) \n\t"
"sw $0, 4(%[x1]) \n\t"
"sw $0, 8(%[x1]) \n\t"
"sw $0, 12(%[x1]) \n\t"
"sw $0, 16(%[x1]) \n\t"
"sw $0, 20(%[x1]) \n\t"
"sw $0, 24(%[x1]) \n\t"
"sw $0, 28(%[x1]) \n\t"
PTR_ADDIU "%[x1],%[x1], 32 \n\t"
"bne %[x1], %[j], 1b \n\t"
PTR_ADDIU "%[x1],%[x1], -19456 \n\t"
: [x1]"+r"(x1)
: [j]"r"(j)
: "memory"
);
if (i_Temp != 0) {
X_low1=&X_low[0][2][0];
for (k = 0; k < sbr->kx[0]; k++) {
__asm__ volatile (
"move %[i], $zero \n\t"
"2: \n\t"
"lw %[temp0], 0(%[X_low1]) \n\t"
"lw %[temp1], 4(%[X_low1]) \n\t"
"sw %[temp0], 0(%[x1]) \n\t"
"sw %[temp1], 9728(%[x1]) \n\t"
PTR_ADDIU "%[x1], %[x1], 256 \n\t"
PTR_ADDIU "%[X_low1], %[X_low1], 8 \n\t"
"addiu %[i], %[i], 1 \n\t"
"bne %[i], %[i_Temp], 2b \n\t"
: [x1]"+r"(x1), [X_low1]"+r"(X_low1), [i]"=&r"(i),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
: [i_Temp]"r"(i_Temp)
: "memory"
);
x1-=(i_Temp<<6)-1;
X_low1-=(i_Temp<<1)-80;
}
x1=&X[0][0][k];
Y01=(float*)&Y0[32][k][0];
for (; k < sbr->kx[0] + sbr->m[0]; k++) {
__asm__ volatile (
"move %[i], $zero \n\t"
"3: \n\t"
"lw %[temp0], 0(%[Y01]) \n\t"
"lw %[temp1], 4(%[Y01]) \n\t"
"sw %[temp0], 0(%[x1]) \n\t"
"sw %[temp1], 9728(%[x1]) \n\t"
PTR_ADDIU "%[x1], %[x1], 256 \n\t"
PTR_ADDIU "%[Y01], %[Y01], 512 \n\t"
"addiu %[i], %[i], 1 \n\t"
"bne %[i], %[i_Temp], 3b \n\t"
: [x1]"+r"(x1), [Y01]"+r"(Y01), [i]"=&r"(i),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
: [i_Temp]"r"(i_Temp)
: "memory"
);
x1 -=(i_Temp<<6)-1;
Y01 -=(i_Temp<<7)-2;
}
}
x1=&X[0][i_Temp][0];
X_low1=&X_low[0][i_Temp+2][0];
temp3=38;
for (k = 0; k < sbr->kx[1]; k++) {
__asm__ volatile (
"move %[i], %[i_Temp] \n\t"
"4: \n\t"
"lw %[temp0], 0(%[X_low1]) \n\t"
"lw %[temp1], 4(%[X_low1]) \n\t"
"sw %[temp0], 0(%[x1]) \n\t"
"sw %[temp1], 9728(%[x1]) \n\t"
PTR_ADDIU "%[x1], %[x1], 256 \n\t"
PTR_ADDIU "%[X_low1],%[X_low1], 8 \n\t"
"addiu %[i], %[i], 1 \n\t"
"bne %[i], %[temp3], 4b \n\t"
: [x1]"+r"(x1), [X_low1]"+r"(X_low1), [i]"=&r"(i),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2)
: [i_Temp]"r"(i_Temp), [temp3]"r"(temp3)
: "memory"
);
x1 -= ((38-i_Temp)<<6)-1;
X_low1 -= ((38-i_Temp)<<1)- 80;
}
x1=&X[0][i_Temp][k];
Y11=&Y1[i_Temp][k][0];
temp2=32;
for (; k < sbr->kx[1] + sbr->m[1]; k++) {
__asm__ volatile (
"move %[i], %[i_Temp] \n\t"
"5: \n\t"
"lw %[temp0], 0(%[Y11]) \n\t"
"lw %[temp1], 4(%[Y11]) \n\t"
"sw %[temp0], 0(%[x1]) \n\t"
"sw %[temp1], 9728(%[x1]) \n\t"
PTR_ADDIU "%[x1], %[x1], 256 \n\t"
PTR_ADDIU "%[Y11], %[Y11], 512 \n\t"
"addiu %[i], %[i], 1 \n\t"
"bne %[i], %[temp2], 5b \n\t"
: [x1]"+r"(x1), [Y11]"+r"(Y11), [i]"=&r"(i),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1)
: [i_Temp]"r"(i_Temp), [temp3]"r"(temp3),
[temp2]"r"(temp2)
: "memory"
);
x1 -= ((32-i_Temp)<<6)-1;
Y11 -= ((32-i_Temp)<<7)-2;
}
return 0;
}
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void sbr_hf_assemble_mips(float Y1[38][64][2],
const float X_high[64][40][2],
SpectralBandReplication *sbr, SBRData *ch_data,
const int e_a[2])
{
int e, i, j, m;
const int h_SL = 4 * !sbr->bs_smoothing_mode;
const int kx = sbr->kx[1];
const int m_max = sbr->m[1];
static const float h_smooth[5] = {
0.33333333333333,
0.30150283239582,
0.21816949906249,
0.11516383427084,
0.03183050093751,
};
float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
int indexnoise = ch_data->f_indexnoise;
int indexsine = ch_data->f_indexsine;
float *g_temp1, *q_temp1, *pok, *pok1;
float temp1, temp2, temp3, temp4;
int size = m_max;
if (sbr->reset) {
for (i = 0; i < h_SL; i++) {
memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0]));
memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
}
} else if (h_SL) {
memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0]));
memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0]));
}
for (e = 0; e < ch_data->bs_num_env; e++) {
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
g_temp1 = g_temp[h_SL + i];
pok = sbr->gain[e];
q_temp1 = q_temp[h_SL + i];
pok1 = sbr->q_m[e];
/* loop unrolled 4 times */
for (j=0; j<(size>>2); j++) {
__asm__ volatile (
"lw %[temp1], 0(%[pok]) \n\t"
"lw %[temp2], 4(%[pok]) \n\t"
"lw %[temp3], 8(%[pok]) \n\t"
"lw %[temp4], 12(%[pok]) \n\t"
"sw %[temp1], 0(%[g_temp1]) \n\t"
"sw %[temp2], 4(%[g_temp1]) \n\t"
"sw %[temp3], 8(%[g_temp1]) \n\t"
"sw %[temp4], 12(%[g_temp1]) \n\t"
"lw %[temp1], 0(%[pok1]) \n\t"
"lw %[temp2], 4(%[pok1]) \n\t"
"lw %[temp3], 8(%[pok1]) \n\t"
"lw %[temp4], 12(%[pok1]) \n\t"
"sw %[temp1], 0(%[q_temp1]) \n\t"
"sw %[temp2], 4(%[q_temp1]) \n\t"
"sw %[temp3], 8(%[q_temp1]) \n\t"
"sw %[temp4], 12(%[q_temp1]) \n\t"
PTR_ADDIU "%[pok], %[pok], 16 \n\t"
PTR_ADDIU "%[g_temp1], %[g_temp1], 16 \n\t"
PTR_ADDIU "%[pok1], %[pok1], 16 \n\t"
PTR_ADDIU "%[q_temp1], %[q_temp1], 16 \n\t"
: [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
[temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
[pok]"+r"(pok), [g_temp1]"+r"(g_temp1),
[pok1]"+r"(pok1), [q_temp1]"+r"(q_temp1)
:
: "memory"
);
}
for (j=0; j<(size&3); j++) {
__asm__ volatile (
"lw %[temp1], 0(%[pok]) \n\t"
"lw %[temp2], 0(%[pok1]) \n\t"
"sw %[temp1], 0(%[g_temp1]) \n\t"
"sw %[temp2], 0(%[q_temp1]) \n\t"
PTR_ADDIU "%[pok], %[pok], 4 \n\t"
PTR_ADDIU "%[g_temp1], %[g_temp1], 4 \n\t"
PTR_ADDIU "%[pok1], %[pok1], 4 \n\t"
PTR_ADDIU "%[q_temp1], %[q_temp1], 4 \n\t"
: [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
[temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
[pok]"+r"(pok), [g_temp1]"+r"(g_temp1),
[pok1]"+r"(pok1), [q_temp1]"+r"(q_temp1)
:
: "memory"
);
}
}
}
for (e = 0; e < ch_data->bs_num_env; e++) {
for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
LOCAL_ALIGNED_16(float, g_filt_tab, [48]);
LOCAL_ALIGNED_16(float, q_filt_tab, [48]);
float *g_filt, *q_filt;
if (h_SL && e != e_a[0] && e != e_a[1]) {
g_filt = g_filt_tab;
q_filt = q_filt_tab;
for (m = 0; m < m_max; m++) {
const int idx1 = i + h_SL;
g_filt[m] = 0.0f;
q_filt[m] = 0.0f;
for (j = 0; j <= h_SL; j++) {
g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j];
q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j];
}
}
} else {
g_filt = g_temp[i + h_SL];
q_filt = q_temp[i];
}
sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
i + ENVELOPE_ADJUSTMENT_OFFSET);
if (e != e_a[0] && e != e_a[1]) {
sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
q_filt, indexnoise,
kx, m_max);
} else {
int idx = indexsine&1;
int A = (1-((indexsine+(kx & 1))&2));
int B = (A^(-idx)) + idx;
float *out = &Y1[i][kx][idx];
float *in = sbr->s_m[e];
float temp0, temp1, temp2, temp3, temp4, temp5;
float A_f = (float)A;
float B_f = (float)B;
for (m = 0; m+1 < m_max; m+=2) {
temp2 = out[0];
temp3 = out[2];
__asm__ volatile(
"lwc1 %[temp0], 0(%[in]) \n\t"
"lwc1 %[temp1], 4(%[in]) \n\t"
"madd.s %[temp4], %[temp2], %[temp0], %[A_f] \n\t"
"madd.s %[temp5], %[temp3], %[temp1], %[B_f] \n\t"
"swc1 %[temp4], 0(%[out]) \n\t"
"swc1 %[temp5], 8(%[out]) \n\t"
PTR_ADDIU "%[in], %[in], 8 \n\t"
PTR_ADDIU "%[out], %[out], 16 \n\t"
: [temp0]"=&f" (temp0), [temp1]"=&f"(temp1),
[temp4]"=&f" (temp4), [temp5]"=&f"(temp5),
[in]"+r"(in), [out]"+r"(out)
: [A_f]"f"(A_f), [B_f]"f"(B_f), [temp2]"f"(temp2),
[temp3]"f"(temp3)
: "memory"
);
}
if(m_max&1)
out[2*m ] += in[m ] * A;
}
indexnoise = (indexnoise + m_max) & 0x1ff;
indexsine = (indexsine + 1) & 3;
}
}
ch_data->f_indexnoise = indexnoise;
ch_data->f_indexsine = indexsine;
}
static void sbr_hf_inverse_filter_mips(SBRDSPContext *dsp,
float (*alpha0)[2], float (*alpha1)[2],
const float X_low[32][40][2], int k0)
{
int k;
float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, c;
float *phi1, *alpha_1, *alpha_0, res1, res2, temp_real, temp_im;
c = 1.000001f;
for (k = 0; k < k0; k++) {
LOCAL_ALIGNED_16(float, phi, [3], [2][2]);
float dk;
phi1 = &phi[0][0][0];
alpha_1 = &alpha1[k][0];
alpha_0 = &alpha0[k][0];
dsp->autocorrelate(X_low[k], phi);
__asm__ volatile (
"lwc1 %[temp0], 40(%[phi1]) \n\t"
"lwc1 %[temp1], 16(%[phi1]) \n\t"
"lwc1 %[temp2], 24(%[phi1]) \n\t"
"lwc1 %[temp3], 28(%[phi1]) \n\t"
"mul.s %[dk], %[temp0], %[temp1] \n\t"
"lwc1 %[temp4], 0(%[phi1]) \n\t"
"mul.s %[res2], %[temp2], %[temp2] \n\t"
"lwc1 %[temp5], 4(%[phi1]) \n\t"
"madd.s %[res2], %[res2], %[temp3], %[temp3] \n\t"
"lwc1 %[temp6], 8(%[phi1]) \n\t"
"div.s %[res2], %[res2], %[c] \n\t"
"lwc1 %[temp0], 12(%[phi1]) \n\t"
"sub.s %[dk], %[dk], %[res2] \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [res2]"=&f"(res2), [dk]"=&f"(dk)
: [phi1]"r"(phi1), [c]"f"(c)
: "memory"
);
if (!dk) {
alpha_1[0] = 0;
alpha_1[1] = 0;
} else {
__asm__ volatile (
"mul.s %[temp_real], %[temp4], %[temp2] \n\t"
"nmsub.s %[temp_real], %[temp_real], %[temp5], %[temp3] \n\t"
"nmsub.s %[temp_real], %[temp_real], %[temp6], %[temp1] \n\t"
"mul.s %[temp_im], %[temp4], %[temp3] \n\t"
"madd.s %[temp_im], %[temp_im], %[temp5], %[temp2] \n\t"
"nmsub.s %[temp_im], %[temp_im], %[temp0], %[temp1] \n\t"
"div.s %[temp_real], %[temp_real], %[dk] \n\t"
"div.s %[temp_im], %[temp_im], %[dk] \n\t"
"swc1 %[temp_real], 0(%[alpha_1]) \n\t"
"swc1 %[temp_im], 4(%[alpha_1]) \n\t"
: [temp_real]"=&f" (temp_real), [temp_im]"=&f"(temp_im)
: [phi1]"r"(phi1), [temp0]"f"(temp0), [temp1]"f"(temp1),
[temp2]"f"(temp2), [temp3]"f"(temp3), [temp4]"f"(temp4),
[temp5]"f"(temp5), [temp6]"f"(temp6),
[alpha_1]"r"(alpha_1), [dk]"f"(dk)
: "memory"
);
}
if (!phi1[4]) {
alpha_0[0] = 0;
alpha_0[1] = 0;
} else {
__asm__ volatile (
"lwc1 %[temp6], 0(%[alpha_1]) \n\t"
"lwc1 %[temp7], 4(%[alpha_1]) \n\t"
"mul.s %[temp_real], %[temp6], %[temp2] \n\t"
"add.s %[temp_real], %[temp_real], %[temp4] \n\t"
"madd.s %[temp_real], %[temp_real], %[temp7], %[temp3] \n\t"
"mul.s %[temp_im], %[temp7], %[temp2] \n\t"
"add.s %[temp_im], %[temp_im], %[temp5] \n\t"
"nmsub.s %[temp_im], %[temp_im], %[temp6], %[temp3] \n\t"
"div.s %[temp_real], %[temp_real], %[temp1] \n\t"
"div.s %[temp_im], %[temp_im], %[temp1] \n\t"
"neg.s %[temp_real], %[temp_real] \n\t"
"neg.s %[temp_im], %[temp_im] \n\t"
"swc1 %[temp_real], 0(%[alpha_0]) \n\t"
"swc1 %[temp_im], 4(%[alpha_0]) \n\t"
: [temp_real]"=&f"(temp_real), [temp_im]"=&f"(temp_im),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7),
[res1]"=&f"(res1), [res2]"=&f"(res2)
: [alpha_1]"r"(alpha_1), [alpha_0]"r"(alpha_0),
[temp0]"f"(temp0), [temp1]"f"(temp1), [temp2]"f"(temp2),
[temp3]"f"(temp3), [temp4]"f"(temp4), [temp5]"f"(temp5)
: "memory"
);
}
__asm__ volatile (
"lwc1 %[temp1], 0(%[alpha_1]) \n\t"
"lwc1 %[temp2], 4(%[alpha_1]) \n\t"
"lwc1 %[temp_real], 0(%[alpha_0]) \n\t"
"lwc1 %[temp_im], 4(%[alpha_0]) \n\t"
"mul.s %[res1], %[temp1], %[temp1] \n\t"
"madd.s %[res1], %[res1], %[temp2], %[temp2] \n\t"
"mul.s %[res2], %[temp_real], %[temp_real] \n\t"
"madd.s %[res2], %[res2], %[temp_im], %[temp_im] \n\t"
: [temp_real]"=&f"(temp_real), [temp_im]"=&f"(temp_im),
[temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[res1]"=&f"(res1), [res2]"=&f"(res2)
: [alpha_1]"r"(alpha_1), [alpha_0]"r"(alpha_0)
: "memory"
);
if (res1 >= 16.0f || res2 >= 16.0f) {
alpha_1[0] = 0;
alpha_1[1] = 0;
alpha_0[0] = 0;
alpha_0[1] = 0;
}
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c)
{
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
c->sbr_lf_gen = sbr_lf_gen_mips;
c->sbr_x_gen = sbr_x_gen_mips;
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->sbr_hf_inverse_filter = sbr_hf_inverse_filter_mips;
c->sbr_hf_assemble = sbr_hf_assemble_mips;
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
}

496
externals/ffmpeg/libavcodec/mips/aacsbr_mips.h vendored Executable file
View File

@@ -0,0 +1,496 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/aacsbr.c
*/
#ifndef AVCODEC_MIPS_AACSBR_MIPS_H
#define AVCODEC_MIPS_AACSBR_MIPS_H
#include "libavcodec/aac.h"
#include "libavcodec/sbr.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
static void sbr_qmf_analysis_mips(AVFloatDSPContext *fdsp, FFTContext *mdct,
SBRDSPContext *sbrdsp, const float *in, float *x,
float z[320], float W[2][32][32][2], int buf_idx)
{
int i;
float *w0;
float *w1;
int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
w0 = x;
w1 = x + 1024;
for(i = 0; i < 36; i++)
{
/* loop unrolled 8 times */
__asm__ volatile(
"lw %[temp0], 0(%[w1]) \n\t"
"lw %[temp1], 4(%[w1]) \n\t"
"lw %[temp2], 8(%[w1]) \n\t"
"lw %[temp3], 12(%[w1]) \n\t"
"lw %[temp4], 16(%[w1]) \n\t"
"lw %[temp5], 20(%[w1]) \n\t"
"lw %[temp6], 24(%[w1]) \n\t"
"lw %[temp7], 28(%[w1]) \n\t"
"sw %[temp0], 0(%[w0]) \n\t"
"sw %[temp1], 4(%[w0]) \n\t"
"sw %[temp2], 8(%[w0]) \n\t"
"sw %[temp3], 12(%[w0]) \n\t"
"sw %[temp4], 16(%[w0]) \n\t"
"sw %[temp5], 20(%[w0]) \n\t"
"sw %[temp6], 24(%[w0]) \n\t"
"sw %[temp7], 28(%[w0]) \n\t"
PTR_ADDIU " %[w0], %[w0], 32 \n\t"
PTR_ADDIU " %[w1], %[w1], 32 \n\t"
: [w0]"+r"(w0), [w1]"+r"(w1),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
:
: "memory"
);
}
w0 = x + 288;
w1 = (float*)in;
for(i = 0; i < 128; i++)
{
/* loop unrolled 8 times */
__asm__ volatile(
"lw %[temp0], 0(%[w1]) \n\t"
"lw %[temp1], 4(%[w1]) \n\t"
"lw %[temp2], 8(%[w1]) \n\t"
"lw %[temp3], 12(%[w1]) \n\t"
"lw %[temp4], 16(%[w1]) \n\t"
"lw %[temp5], 20(%[w1]) \n\t"
"lw %[temp6], 24(%[w1]) \n\t"
"lw %[temp7], 28(%[w1]) \n\t"
"sw %[temp0], 0(%[w0]) \n\t"
"sw %[temp1], 4(%[w0]) \n\t"
"sw %[temp2], 8(%[w0]) \n\t"
"sw %[temp3], 12(%[w0]) \n\t"
"sw %[temp4], 16(%[w0]) \n\t"
"sw %[temp5], 20(%[w0]) \n\t"
"sw %[temp6], 24(%[w0]) \n\t"
"sw %[temp7], 28(%[w0]) \n\t"
PTR_ADDIU " %[w0], %[w0], 32 \n\t"
PTR_ADDIU " %[w1], %[w1], 32 \n\t"
: [w0]"+r"(w0), [w1]"+r"(w1),
[temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
[temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
[temp4]"=&r"(temp4), [temp5]"=&r"(temp5),
[temp6]"=&r"(temp6), [temp7]"=&r"(temp7)
:
: "memory"
);
}
for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
// are not supported
fdsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
sbrdsp->sum64x5(z);
sbrdsp->qmf_pre_shuffle(z);
mdct->imdct_half(mdct, z, z+64);
sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
x += 32;
}
}
#if HAVE_MIPSFPU
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void sbr_qmf_synthesis_mips(FFTContext *mdct,
SBRDSPContext *sbrdsp, AVFloatDSPContext *fdsp,
float *out, float X[2][38][64],
float mdct_buf[2][64],
float *v0, int *v_off, const unsigned int div)
{
int i, n;
const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
const int step = 128 >> div;
float *v;
float temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11, temp12, temp13;
float temp14, temp15, temp16, temp17, temp18, temp19;
float *vv0, *s0, *dst;
dst = out;
for (i = 0; i < 32; i++) {
if (*v_off < step) {
int saved_samples = (1280 - 128) >> div;
memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float));
*v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step;
} else {
*v_off -= step;
}
v = v0 + *v_off;
if (div) {
for (n = 0; n < 32; n++) {
X[0][i][ n] = -X[0][i][n];
X[0][i][32+n] = X[1][i][31-n];
}
mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
sbrdsp->qmf_deint_neg(v, mdct_buf[0]);
} else {
sbrdsp->neg_odd_64(X[1][i]);
mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
}
if(div == 0)
{
float *v0_end;
vv0 = v;
v0_end = v + 60;
s0 = (float*)sbr_qmf_window;
/* 10 calls of function vector_fmul_add merged into one loop
and loop unrolled 4 times */
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"lwc1 %[temp4], 0(%[v0]) \n\t"
"lwc1 %[temp5], 0(%[s0]) \n\t"
"lwc1 %[temp6], 4(%[v0]) \n\t"
"lwc1 %[temp7], 4(%[s0]) \n\t"
"lwc1 %[temp8], 8(%[v0]) \n\t"
"lwc1 %[temp9], 8(%[s0]) \n\t"
"lwc1 %[temp10], 12(%[v0]) \n\t"
"lwc1 %[temp11], 12(%[s0]) \n\t"
"lwc1 %[temp12], 768(%[v0]) \n\t"
"lwc1 %[temp13], 256(%[s0]) \n\t"
"lwc1 %[temp14], 772(%[v0]) \n\t"
"lwc1 %[temp15], 260(%[s0]) \n\t"
"lwc1 %[temp16], 776(%[v0]) \n\t"
"lwc1 %[temp17], 264(%[s0]) \n\t"
"lwc1 %[temp18], 780(%[v0]) \n\t"
"lwc1 %[temp19], 268(%[s0]) \n\t"
"1: \n\t"
"mul.s %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 1024(%[v0]) \n\t"
"mul.s %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 512(%[s0]) \n\t"
"mul.s %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 1028(%[v0]) \n\t"
"mul.s %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 516(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 1032(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 520(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 1036(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 524(%[s0]) \n\t"
"lwc1 %[temp12], 1792(%[v0]) \n\t"
"lwc1 %[temp13], 768(%[s0]) \n\t"
"lwc1 %[temp14], 1796(%[v0]) \n\t"
"lwc1 %[temp15], 772(%[s0]) \n\t"
"lwc1 %[temp16], 1800(%[v0]) \n\t"
"lwc1 %[temp17], 776(%[s0]) \n\t"
"lwc1 %[temp18], 1804(%[v0]) \n\t"
"lwc1 %[temp19], 780(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 2048(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 1024(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 2052(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 1028(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 2056(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 1032(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 2060(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 1036(%[s0]) \n\t"
"lwc1 %[temp12], 2816(%[v0]) \n\t"
"lwc1 %[temp13], 1280(%[s0]) \n\t"
"lwc1 %[temp14], 2820(%[v0]) \n\t"
"lwc1 %[temp15], 1284(%[s0]) \n\t"
"lwc1 %[temp16], 2824(%[v0]) \n\t"
"lwc1 %[temp17], 1288(%[s0]) \n\t"
"lwc1 %[temp18], 2828(%[v0]) \n\t"
"lwc1 %[temp19], 1292(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 3072(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 1536(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 3076(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 1540(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 3080(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 1544(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 3084(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 1548(%[s0]) \n\t"
"lwc1 %[temp12], 3840(%[v0]) \n\t"
"lwc1 %[temp13], 1792(%[s0]) \n\t"
"lwc1 %[temp14], 3844(%[v0]) \n\t"
"lwc1 %[temp15], 1796(%[s0]) \n\t"
"lwc1 %[temp16], 3848(%[v0]) \n\t"
"lwc1 %[temp17], 1800(%[s0]) \n\t"
"lwc1 %[temp18], 3852(%[v0]) \n\t"
"lwc1 %[temp19], 1804(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 4096(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 2048(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 4100(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 2052(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 4104(%[v0]) \n\t"
PTR_ADDIU "%[dst], %[dst], 16 \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 2056(%[s0]) \n\t"
PTR_ADDIU " %[s0], %[s0], 16 \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 4108(%[v0]) \n\t"
PTR_ADDIU " %[v0], %[v0], 16 \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 2044(%[s0]) \n\t"
"lwc1 %[temp12], 4848(%[v0]) \n\t"
"lwc1 %[temp13], 2288(%[s0]) \n\t"
"lwc1 %[temp14], 4852(%[v0]) \n\t"
"lwc1 %[temp15], 2292(%[s0]) \n\t"
"lwc1 %[temp16], 4856(%[v0]) \n\t"
"lwc1 %[temp17], 2296(%[s0]) \n\t"
"lwc1 %[temp18], 4860(%[v0]) \n\t"
"lwc1 %[temp19], 2300(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 0(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 0(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 4(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 4(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 8(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 8(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 12(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 12(%[s0]) \n\t"
"lwc1 %[temp12], 768(%[v0]) \n\t"
"lwc1 %[temp13], 256(%[s0]) \n\t"
"lwc1 %[temp14], 772(%[v0]) \n\t"
"lwc1 %[temp15], 260(%[s0]) \n\t"
"lwc1 %[temp16], 776(%[v0]) \n\t"
"lwc1 %[temp17], 264(%[s0]) \n\t"
"lwc1 %[temp18], 780(%[v0]) \n\t"
"lwc1 %[temp19], 268(%[s0]) \n\t"
"swc1 %[temp0], -16(%[dst]) \n\t"
"swc1 %[temp1], -12(%[dst]) \n\t"
"swc1 %[temp2], -8(%[dst]) \n\t"
"bne %[v0], %[v0_end], 1b \n\t"
" swc1 %[temp3], -4(%[dst]) \n\t"
"mul.s %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 1024(%[v0]) \n\t"
"mul.s %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 512(%[s0]) \n\t"
"mul.s %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 1028(%[v0]) \n\t"
"mul.s %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 516(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 1032(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 520(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 1036(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 524(%[s0]) \n\t"
"lwc1 %[temp12], 1792(%[v0]) \n\t"
"lwc1 %[temp13], 768(%[s0]) \n\t"
"lwc1 %[temp14], 1796(%[v0]) \n\t"
"lwc1 %[temp15], 772(%[s0]) \n\t"
"lwc1 %[temp16], 1800(%[v0]) \n\t"
"lwc1 %[temp17], 776(%[s0]) \n\t"
"lwc1 %[temp18], 1804(%[v0]) \n\t"
"lwc1 %[temp19], 780(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 2048(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 1024(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 2052(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 1028(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 2056(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 1032(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 2060(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 1036(%[s0]) \n\t"
"lwc1 %[temp12], 2816(%[v0]) \n\t"
"lwc1 %[temp13], 1280(%[s0]) \n\t"
"lwc1 %[temp14], 2820(%[v0]) \n\t"
"lwc1 %[temp15], 1284(%[s0]) \n\t"
"lwc1 %[temp16], 2824(%[v0]) \n\t"
"lwc1 %[temp17], 1288(%[s0]) \n\t"
"lwc1 %[temp18], 2828(%[v0]) \n\t"
"lwc1 %[temp19], 1292(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 3072(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 1536(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 3076(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 1540(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 3080(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 1544(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 3084(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 1548(%[s0]) \n\t"
"lwc1 %[temp12], 3840(%[v0]) \n\t"
"lwc1 %[temp13], 1792(%[s0]) \n\t"
"lwc1 %[temp14], 3844(%[v0]) \n\t"
"lwc1 %[temp15], 1796(%[s0]) \n\t"
"lwc1 %[temp16], 3848(%[v0]) \n\t"
"lwc1 %[temp17], 1800(%[s0]) \n\t"
"lwc1 %[temp18], 3852(%[v0]) \n\t"
"lwc1 %[temp19], 1804(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp4], 4096(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp5], 2048(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp6], 4100(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp7], 2052(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
"lwc1 %[temp8], 4104(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"lwc1 %[temp9], 2056(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"lwc1 %[temp10], 4108(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"lwc1 %[temp11], 2060(%[s0]) \n\t"
"lwc1 %[temp12], 4864(%[v0]) \n\t"
"lwc1 %[temp13], 2304(%[s0]) \n\t"
"lwc1 %[temp14], 4868(%[v0]) \n\t"
"lwc1 %[temp15], 2308(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp4], %[temp5] \n\t"
"lwc1 %[temp16], 4872(%[v0]) \n\t"
"madd.s %[temp1], %[temp1], %[temp6], %[temp7] \n\t"
"lwc1 %[temp17], 2312(%[s0]) \n\t"
"madd.s %[temp2], %[temp2], %[temp8], %[temp9] \n\t"
"lwc1 %[temp18], 4876(%[v0]) \n\t"
"madd.s %[temp3], %[temp3], %[temp10], %[temp11] \n\t"
"lwc1 %[temp19], 2316(%[s0]) \n\t"
"madd.s %[temp0], %[temp0], %[temp12], %[temp13] \n\t"
PTR_ADDIU "%[dst], %[dst], 16 \n\t"
"madd.s %[temp1], %[temp1], %[temp14], %[temp15] \n\t"
"madd.s %[temp2], %[temp2], %[temp16], %[temp17] \n\t"
"madd.s %[temp3], %[temp3], %[temp18], %[temp19] \n\t"
"swc1 %[temp0], -16(%[dst]) \n\t"
"swc1 %[temp1], -12(%[dst]) \n\t"
"swc1 %[temp2], -8(%[dst]) \n\t"
"swc1 %[temp3], -4(%[dst]) \n\t"
".set pop \n\t"
: [dst]"+r"(dst), [v0]"+r"(vv0), [s0]"+r"(s0),
[temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
[temp12]"=&f"(temp12), [temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
[temp15]"=&f"(temp15), [temp16]"=&f"(temp16), [temp17]"=&f"(temp17),
[temp18]"=&f"(temp18), [temp19]"=&f"(temp19)
: [v0_end]"r"(v0_end)
: "memory"
);
}
else
{
fdsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div);
fdsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div);
out += 64 >> div;
}
}
}
#define sbr_qmf_analysis sbr_qmf_analysis_mips
#define sbr_qmf_synthesis sbr_qmf_synthesis_mips
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_MIPS_AACSBR_MIPS_H */

417
externals/ffmpeg/libavcodec/mips/ac3dsp_mips.c vendored Executable file
View File

@@ -0,0 +1,417 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Branimir Vasic (bvasic@mips.com)
* Nedeljko Babic (nbabic@mips.com)
*
* Various AC-3 DSP Utils optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/ac3dsp.c
*/
#include "config.h"
#include "libavcodec/ac3dsp.h"
#include "libavcodec/ac3.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if HAVE_MIPSDSP
static void ac3_bit_alloc_calc_bap_mips(int16_t *mask, int16_t *psd,
int start, int end,
int snr_offset, int floor,
const uint8_t *bap_tab, uint8_t *bap)
{
int band, band_end, cond;
int m, address1, address2;
int16_t *psd1, *psd_end;
uint8_t *bap1;
if (snr_offset == -960) {
memset(bap, 0, AC3_MAX_COEFS);
return;
}
psd1 = &psd[start];
bap1 = &bap[start];
band = ff_ac3_bin_to_band_tab[start];
do {
m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
band_end = ff_ac3_band_start_tab[++band];
band_end = FFMIN(band_end, end);
psd_end = psd + band_end - 1;
__asm__ volatile (
"slt %[cond], %[psd1], %[psd_end] \n\t"
"beqz %[cond], 1f \n\t"
"2: \n\t"
"lh %[address1], 0(%[psd1]) \n\t"
"lh %[address2], 2(%[psd1]) \n\t"
PTR_ADDIU " %[psd1], %[psd1], 4 \n\t"
"subu %[address1], %[address1], %[m] \n\t"
"sra %[address1], %[address1], 5 \n\t"
"addiu %[address1], %[address1], -32 \n\t"
"shll_s.w %[address1], %[address1], 26 \n\t"
"subu %[address2], %[address2], %[m] \n\t"
"sra %[address2], %[address2], 5 \n\t"
"sra %[address1], %[address1], 26 \n\t"
"addiu %[address1], %[address1], 32 \n\t"
"lbux %[address1], %[address1](%[bap_tab]) \n\t"
"addiu %[address2], %[address2], -32 \n\t"
"shll_s.w %[address2], %[address2], 26 \n\t"
"sb %[address1], 0(%[bap1]) \n\t"
"slt %[cond], %[psd1], %[psd_end] \n\t"
"sra %[address2], %[address2], 26 \n\t"
"addiu %[address2], %[address2], 32 \n\t"
"lbux %[address2], %[address2](%[bap_tab]) \n\t"
"sb %[address2], 1(%[bap1]) \n\t"
PTR_ADDIU " %[bap1], %[bap1], 2 \n\t"
"bnez %[cond], 2b \n\t"
PTR_ADDIU " %[psd_end], %[psd_end], 2 \n\t"
"slt %[cond], %[psd1], %[psd_end] \n\t"
"beqz %[cond], 3f \n\t"
"1: \n\t"
"lh %[address1], 0(%[psd1]) \n\t"
PTR_ADDIU " %[psd1], %[psd1], 2 \n\t"
"subu %[address1], %[address1], %[m] \n\t"
"sra %[address1], %[address1], 5 \n\t"
"addiu %[address1], %[address1], -32 \n\t"
"shll_s.w %[address1], %[address1], 26 \n\t"
"sra %[address1], %[address1], 26 \n\t"
"addiu %[address1], %[address1], 32 \n\t"
"lbux %[address1], %[address1](%[bap_tab]) \n\t"
"sb %[address1], 0(%[bap1]) \n\t"
PTR_ADDIU " %[bap1], %[bap1], 1 \n\t"
"3: \n\t"
: [address1]"=&r"(address1), [address2]"=&r"(address2),
[cond]"=&r"(cond), [bap1]"+r"(bap1),
[psd1]"+r"(psd1), [psd_end]"+r"(psd_end)
: [m]"r"(m), [bap_tab]"r"(bap_tab)
: "memory"
);
} while (end > band_end);
}
static void ac3_update_bap_counts_mips(uint16_t mant_cnt[16], uint8_t *bap,
int len)
{
void *temp0, *temp2, *temp4, *temp5, *temp6, *temp7;
int temp1, temp3;
__asm__ volatile (
"andi %[temp3], %[len], 3 \n\t"
PTR_ADDU "%[temp2], %[bap], %[len] \n\t"
PTR_ADDU "%[temp4], %[bap], %[temp3] \n\t"
"beq %[temp2], %[temp4], 4f \n\t"
"1: \n\t"
"lbu %[temp0], -1(%[temp2]) \n\t"
"lbu %[temp5], -2(%[temp2]) \n\t"
"lbu %[temp6], -3(%[temp2]) \n\t"
"sll %[temp0], %[temp0], 1 \n\t"
PTR_ADDU "%[temp0], %[mant_cnt], %[temp0] \n\t"
"sll %[temp5], %[temp5], 1 \n\t"
PTR_ADDU "%[temp5], %[mant_cnt], %[temp5] \n\t"
"lhu %[temp1], 0(%[temp0]) \n\t"
"sll %[temp6], %[temp6], 1 \n\t"
PTR_ADDU "%[temp6], %[mant_cnt], %[temp6] \n\t"
"addiu %[temp1], %[temp1], 1 \n\t"
"sh %[temp1], 0(%[temp0]) \n\t"
"lhu %[temp1], 0(%[temp5]) \n\t"
"lbu %[temp7], -4(%[temp2]) \n\t"
PTR_ADDIU "%[temp2],%[temp2], -4 \n\t"
"addiu %[temp1], %[temp1], 1 \n\t"
"sh %[temp1], 0(%[temp5]) \n\t"
"lhu %[temp1], 0(%[temp6]) \n\t"
"sll %[temp7], %[temp7], 1 \n\t"
PTR_ADDU "%[temp7], %[mant_cnt], %[temp7] \n\t"
"addiu %[temp1], %[temp1],1 \n\t"
"sh %[temp1], 0(%[temp6]) \n\t"
"lhu %[temp1], 0(%[temp7]) \n\t"
"addiu %[temp1], %[temp1], 1 \n\t"
"sh %[temp1], 0(%[temp7]) \n\t"
"bne %[temp2], %[temp4], 1b \n\t"
"4: \n\t"
"beqz %[temp3], 2f \n\t"
"3: \n\t"
"addiu %[temp3], %[temp3], -1 \n\t"
"lbu %[temp0], -1(%[temp2]) \n\t"
PTR_ADDIU "%[temp2],%[temp2], -1 \n\t"
"sll %[temp0], %[temp0], 1 \n\t"
PTR_ADDU "%[temp0], %[mant_cnt], %[temp0] \n\t"
"lhu %[temp1], 0(%[temp0]) \n\t"
"addiu %[temp1], %[temp1], 1 \n\t"
"sh %[temp1], 0(%[temp0]) \n\t"
"bgtz %[temp3], 3b \n\t"
"2: \n\t"
: [temp0] "=&r" (temp0), [temp1] "=&r" (temp1),
[temp2] "=&r" (temp2), [temp3] "=&r" (temp3),
[temp4] "=&r" (temp4), [temp5] "=&r" (temp5),
[temp6] "=&r" (temp6), [temp7] "=&r" (temp7)
: [len] "r" (len), [bap] "r" (bap),
[mant_cnt] "r" (mant_cnt)
: "memory"
);
}
#endif
#if HAVE_MIPSFPU
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void float_to_fixed24_mips(int32_t *dst, const float *src, unsigned int len)
{
const float scale = 1 << 24;
float src0, src1, src2, src3, src4, src5, src6, src7;
int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
do {
__asm__ volatile (
"lwc1 %[src0], 0(%[src]) \n\t"
"lwc1 %[src1], 4(%[src]) \n\t"
"lwc1 %[src2], 8(%[src]) \n\t"
"lwc1 %[src3], 12(%[src]) \n\t"
"lwc1 %[src4], 16(%[src]) \n\t"
"lwc1 %[src5], 20(%[src]) \n\t"
"lwc1 %[src6], 24(%[src]) \n\t"
"lwc1 %[src7], 28(%[src]) \n\t"
"mul.s %[src0], %[src0], %[scale] \n\t"
"mul.s %[src1], %[src1], %[scale] \n\t"
"mul.s %[src2], %[src2], %[scale] \n\t"
"mul.s %[src3], %[src3], %[scale] \n\t"
"mul.s %[src4], %[src4], %[scale] \n\t"
"mul.s %[src5], %[src5], %[scale] \n\t"
"mul.s %[src6], %[src6], %[scale] \n\t"
"mul.s %[src7], %[src7], %[scale] \n\t"
"cvt.w.s %[src0], %[src0] \n\t"
"cvt.w.s %[src1], %[src1] \n\t"
"cvt.w.s %[src2], %[src2] \n\t"
"cvt.w.s %[src3], %[src3] \n\t"
"cvt.w.s %[src4], %[src4] \n\t"
"cvt.w.s %[src5], %[src5] \n\t"
"cvt.w.s %[src6], %[src6] \n\t"
"cvt.w.s %[src7], %[src7] \n\t"
"mfc1 %[temp0], %[src0] \n\t"
"mfc1 %[temp1], %[src1] \n\t"
"mfc1 %[temp2], %[src2] \n\t"
"mfc1 %[temp3], %[src3] \n\t"
"mfc1 %[temp4], %[src4] \n\t"
"mfc1 %[temp5], %[src5] \n\t"
"mfc1 %[temp6], %[src6] \n\t"
"mfc1 %[temp7], %[src7] \n\t"
"sw %[temp0], 0(%[dst]) \n\t"
"sw %[temp1], 4(%[dst]) \n\t"
"sw %[temp2], 8(%[dst]) \n\t"
"sw %[temp3], 12(%[dst]) \n\t"
"sw %[temp4], 16(%[dst]) \n\t"
"sw %[temp5], 20(%[dst]) \n\t"
"sw %[temp6], 24(%[dst]) \n\t"
"sw %[temp7], 28(%[dst]) \n\t"
: [dst] "+r" (dst), [src] "+r" (src),
[src0] "=&f" (src0), [src1] "=&f" (src1),
[src2] "=&f" (src2), [src3] "=&f" (src3),
[src4] "=&f" (src4), [src5] "=&f" (src5),
[src6] "=&f" (src6), [src7] "=&f" (src7),
[temp0] "=r" (temp0), [temp1] "=r" (temp1),
[temp2] "=r" (temp2), [temp3] "=r" (temp3),
[temp4] "=r" (temp4), [temp5] "=r" (temp5),
[temp6] "=r" (temp6), [temp7] "=r" (temp7)
: [scale] "f" (scale)
: "memory"
);
src = src + 8;
dst = dst + 8;
len -= 8;
} while (len > 0);
}
static void ac3_downmix_mips(float **samples, float (*matrix)[2],
int out_ch, int in_ch, int len)
{
int i, j, i1, i2, i3;
float v0, v1, v2, v3;
float v4, v5, v6, v7;
float samples0, samples1, samples2, samples3, matrix_j, matrix_j2;
float *samples_p, *samples_sw, *matrix_p, **samples_x, **samples_end;
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"li %[i1], 2 \n\t"
"sll %[len], 2 \n\t"
"move %[i], $zero \n\t"
"sll %[j], %[in_ch], " PTRLOG " \n\t"
"bne %[out_ch], %[i1], 3f \n\t" // if (out_ch == 2)
" li %[i2], 1 \n\t"
"2: \n\t" // start of the for loop (for (i = 0; i < len; i+=4))
"move %[matrix_p], %[matrix] \n\t"
"move %[samples_x], %[samples] \n\t"
"mtc1 $zero, %[v0] \n\t"
"mtc1 $zero, %[v1] \n\t"
"mtc1 $zero, %[v2] \n\t"
"mtc1 $zero, %[v3] \n\t"
"mtc1 $zero, %[v4] \n\t"
"mtc1 $zero, %[v5] \n\t"
"mtc1 $zero, %[v6] \n\t"
"mtc1 $zero, %[v7] \n\t"
"addiu %[i1], %[i], 4 \n\t"
"addiu %[i2], %[i], 8 \n\t"
PTR_L " %[samples_p], 0(%[samples_x]) \n\t"
"addiu %[i3], %[i], 12 \n\t"
PTR_ADDU "%[samples_end],%[samples_x], %[j] \n\t"
"move %[samples_sw], %[samples_p] \n\t"
"1: \n\t" // start of the inner for loop (for (j = 0; j < in_ch; j++))
"lwc1 %[matrix_j], 0(%[matrix_p]) \n\t"
"lwc1 %[matrix_j2], 4(%[matrix_p]) \n\t"
"lwxc1 %[samples0], %[i](%[samples_p]) \n\t"
"lwxc1 %[samples1], %[i1](%[samples_p]) \n\t"
"lwxc1 %[samples2], %[i2](%[samples_p]) \n\t"
"lwxc1 %[samples3], %[i3](%[samples_p]) \n\t"
PTR_ADDIU "%[matrix_p], 8 \n\t"
PTR_ADDIU "%[samples_x]," PTRSIZE " \n\t"
"madd.s %[v0], %[v0], %[samples0], %[matrix_j] \n\t"
"madd.s %[v1], %[v1], %[samples1], %[matrix_j] \n\t"
"madd.s %[v2], %[v2], %[samples2], %[matrix_j] \n\t"
"madd.s %[v3], %[v3], %[samples3], %[matrix_j] \n\t"
"madd.s %[v4], %[v4], %[samples0], %[matrix_j2]\n\t"
"madd.s %[v5], %[v5], %[samples1], %[matrix_j2]\n\t"
"madd.s %[v6], %[v6], %[samples2], %[matrix_j2]\n\t"
"madd.s %[v7], %[v7], %[samples3], %[matrix_j2]\n\t"
"bne %[samples_x], %[samples_end], 1b \n\t"
PTR_L " %[samples_p], 0(%[samples_x]) \n\t"
PTR_L " %[samples_p], " PTRSIZE "(%[samples]) \n\t"
"swxc1 %[v0], %[i](%[samples_sw]) \n\t"
"swxc1 %[v1], %[i1](%[samples_sw]) \n\t"
"swxc1 %[v2], %[i2](%[samples_sw]) \n\t"
"swxc1 %[v3], %[i3](%[samples_sw]) \n\t"
"swxc1 %[v4], %[i](%[samples_p]) \n\t"
"addiu %[i], 16 \n\t"
"swxc1 %[v5], %[i1](%[samples_p]) \n\t"
"swxc1 %[v6], %[i2](%[samples_p]) \n\t"
"bne %[i], %[len], 2b \n\t"
" swxc1 %[v7], %[i3](%[samples_p]) \n\t"
"3: \n\t"
"bne %[out_ch], %[i2], 6f \n\t" // if (out_ch == 1)
" nop \n\t"
"5: \n\t" // start of the outer for loop (for (i = 0; i < len; i+=4))
"move %[matrix_p], %[matrix] \n\t"
"move %[samples_x], %[samples] \n\t"
"mtc1 $zero, %[v0] \n\t"
"mtc1 $zero, %[v1] \n\t"
"mtc1 $zero, %[v2] \n\t"
"mtc1 $zero, %[v3] \n\t"
"addiu %[i1], %[i], 4 \n\t"
"addiu %[i2], %[i], 8 \n\t"
PTR_L " %[samples_p], 0(%[samples_x]) \n\t"
"addiu %[i3], %[i], 12 \n\t"
PTR_ADDU "%[samples_end],%[samples_x], %[j] \n\t"
"move %[samples_sw], %[samples_p] \n\t"
"4: \n\t" // start of the inner for loop (for (j = 0; j < in_ch; j++))
"lwc1 %[matrix_j], 0(%[matrix_p]) \n\t"
"lwxc1 %[samples0], %[i](%[samples_p]) \n\t"
"lwxc1 %[samples1], %[i1](%[samples_p]) \n\t"
"lwxc1 %[samples2], %[i2](%[samples_p]) \n\t"
"lwxc1 %[samples3], %[i3](%[samples_p]) \n\t"
PTR_ADDIU "%[matrix_p], 8 \n\t"
PTR_ADDIU "%[samples_x]," PTRSIZE " \n\t"
"madd.s %[v0], %[v0], %[samples0], %[matrix_j] \n\t"
"madd.s %[v1], %[v1], %[samples1], %[matrix_j] \n\t"
"madd.s %[v2], %[v2], %[samples2], %[matrix_j] \n\t"
"madd.s %[v3], %[v3], %[samples3], %[matrix_j] \n\t"
"bne %[samples_x], %[samples_end], 4b \n\t"
PTR_L " %[samples_p], 0(%[samples_x]) \n\t"
"swxc1 %[v0], %[i](%[samples_sw]) \n\t"
"addiu %[i], 16 \n\t"
"swxc1 %[v1], %[i1](%[samples_sw]) \n\t"
"swxc1 %[v2], %[i2](%[samples_sw]) \n\t"
"bne %[i], %[len], 5b \n\t"
" swxc1 %[v3], %[i3](%[samples_sw]) \n\t"
"6: \n\t"
".set pop"
:[samples_p]"=&r"(samples_p), [matrix_j]"=&f"(matrix_j), [matrix_j2]"=&f"(matrix_j2),
[samples0]"=&f"(samples0), [samples1]"=&f"(samples1),
[samples2]"=&f"(samples2), [samples3]"=&f"(samples3),
[v0]"=&f"(v0), [v1]"=&f"(v1), [v2]"=&f"(v2), [v3]"=&f"(v3),
[v4]"=&f"(v4), [v5]"=&f"(v5), [v6]"=&f"(v6), [v7]"=&f"(v7),
[samples_x]"=&r"(samples_x), [matrix_p]"=&r"(matrix_p),
[samples_end]"=&r"(samples_end), [samples_sw]"=&r"(samples_sw),
[i1]"=&r"(i1), [i2]"=&r"(i2), [i3]"=&r"(i3), [i]"=&r"(i),
[j]"=&r"(j), [len]"+r"(len)
:[samples]"r"(samples), [matrix]"r"(matrix),
[in_ch]"r"(in_ch), [out_ch]"r"(out_ch)
:"memory"
);
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
void ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact) {
#if HAVE_INLINE_ASM
#if HAVE_MIPSDSP
c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_mips;
c->update_bap_counts = ac3_update_bap_counts_mips;
#endif
#if HAVE_MIPSFPU
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->float_to_fixed24 = float_to_fixed24_mips;
//c->downmix = ac3_downmix_mips;
#endif
#endif
#endif
}

View File

@@ -0,0 +1,221 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* various filters for ACELP-based codecs optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/acelp_filters.c
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavcodec/acelp_filters.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ff_acelp_interpolatef_mips(float *out, const float *in,
const float *filter_coeffs, int precision,
int frac_pos, int filter_length, int length)
{
int n, i;
int prec = precision * 4;
int fc_offset = precision - frac_pos;
float in_val_p, in_val_m, fc_val_p, fc_val_m;
for (n = 0; n < length; n++) {
/**
* four pointers are defined in order to minimize number of
* computations done in inner loop
*/
const float *p_in_p = &in[n];
const float *p_in_m = &in[n-1];
const float *p_filter_coeffs_p = &filter_coeffs[frac_pos];
const float *p_filter_coeffs_m = filter_coeffs + fc_offset;
float v = 0;
for (i = 0; i < filter_length;i++) {
__asm__ volatile (
"lwc1 %[in_val_p], 0(%[p_in_p]) \n\t"
"lwc1 %[fc_val_p], 0(%[p_filter_coeffs_p]) \n\t"
"lwc1 %[in_val_m], 0(%[p_in_m]) \n\t"
"lwc1 %[fc_val_m], 0(%[p_filter_coeffs_m]) \n\t"
PTR_ADDIU "%[p_in_p], %[p_in_p], 4 \n\t"
"madd.s %[v],%[v], %[in_val_p],%[fc_val_p] \n\t"
PTR_ADDIU "%[p_in_m], %[p_in_m], -4 \n\t"
PTR_ADDU "%[p_filter_coeffs_p],%[p_filter_coeffs_p], %[prec] \n\t"
PTR_ADDU "%[p_filter_coeffs_m],%[p_filter_coeffs_m], %[prec] \n\t"
"madd.s %[v],%[v],%[in_val_m], %[fc_val_m] \n\t"
: [v] "+&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m),
[p_filter_coeffs_p] "+r" (p_filter_coeffs_p),
[in_val_p] "=&f" (in_val_p), [in_val_m] "=&f" (in_val_m),
[fc_val_p] "=&f" (fc_val_p), [fc_val_m] "=&f" (fc_val_m),
[p_filter_coeffs_m] "+r" (p_filter_coeffs_m)
: [prec] "r" (prec)
: "memory"
);
}
out[n] = v;
}
}
static void ff_acelp_apply_order_2_transfer_function_mips(float *out, const float *in,
const float zero_coeffs[2],
const float pole_coeffs[2],
float gain, float mem[2], int n)
{
/**
* loop is unrolled eight times
*/
__asm__ volatile (
"lwc1 $f0, 0(%[mem]) \n\t"
"blez %[n], ff_acelp_apply_order_2_transfer_function_end%= \n\t"
"lwc1 $f1, 4(%[mem]) \n\t"
"lwc1 $f2, 0(%[pole_coeffs]) \n\t"
"lwc1 $f3, 4(%[pole_coeffs]) \n\t"
"lwc1 $f4, 0(%[zero_coeffs]) \n\t"
"lwc1 $f5, 4(%[zero_coeffs]) \n\t"
"ff_acelp_apply_order_2_transfer_function_madd%=: \n\t"
"lwc1 $f6, 0(%[in]) \n\t"
"mul.s $f9, $f3, $f1 \n\t"
"mul.s $f7, $f2, $f0 \n\t"
"msub.s $f7, $f7, %[gain], $f6 \n\t"
"sub.s $f7, $f7, $f9 \n\t"
"madd.s $f8, $f7, $f4, $f0 \n\t"
"madd.s $f8, $f8, $f5, $f1 \n\t"
"lwc1 $f11, 4(%[in]) \n\t"
"mul.s $f12, $f3, $f0 \n\t"
"mul.s $f13, $f2, $f7 \n\t"
"msub.s $f13, $f13, %[gain], $f11 \n\t"
"sub.s $f13, $f13, $f12 \n\t"
"madd.s $f14, $f13, $f4, $f7 \n\t"
"madd.s $f14, $f14, $f5, $f0 \n\t"
"swc1 $f8, 0(%[out]) \n\t"
"lwc1 $f6, 8(%[in]) \n\t"
"mul.s $f9, $f3, $f7 \n\t"
"mul.s $f15, $f2, $f13 \n\t"
"msub.s $f15, $f15, %[gain], $f6 \n\t"
"sub.s $f15, $f15, $f9 \n\t"
"madd.s $f8, $f15, $f4, $f13 \n\t"
"madd.s $f8, $f8, $f5, $f7 \n\t"
"swc1 $f14, 4(%[out]) \n\t"
"lwc1 $f11, 12(%[in]) \n\t"
"mul.s $f12, $f3, $f13 \n\t"
"mul.s $f16, $f2, $f15 \n\t"
"msub.s $f16, $f16, %[gain], $f11 \n\t"
"sub.s $f16, $f16, $f12 \n\t"
"madd.s $f14, $f16, $f4, $f15 \n\t"
"madd.s $f14, $f14, $f5, $f13 \n\t"
"swc1 $f8, 8(%[out]) \n\t"
"lwc1 $f6, 16(%[in]) \n\t"
"mul.s $f9, $f3, $f15 \n\t"
"mul.s $f7, $f2, $f16 \n\t"
"msub.s $f7, $f7, %[gain], $f6 \n\t"
"sub.s $f7, $f7, $f9 \n\t"
"madd.s $f8, $f7, $f4, $f16 \n\t"
"madd.s $f8, $f8, $f5, $f15 \n\t"
"swc1 $f14, 12(%[out]) \n\t"
"lwc1 $f11, 20(%[in]) \n\t"
"mul.s $f12, $f3, $f16 \n\t"
"mul.s $f13, $f2, $f7 \n\t"
"msub.s $f13, $f13, %[gain], $f11 \n\t"
"sub.s $f13, $f13, $f12 \n\t"
"madd.s $f14, $f13, $f4, $f7 \n\t"
"madd.s $f14, $f14, $f5, $f16 \n\t"
"swc1 $f8, 16(%[out]) \n\t"
"lwc1 $f6, 24(%[in]) \n\t"
"mul.s $f9, $f3, $f7 \n\t"
"mul.s $f15, $f2, $f13 \n\t"
"msub.s $f15, $f15, %[gain], $f6 \n\t"
"sub.s $f1, $f15, $f9 \n\t"
"madd.s $f8, $f1, $f4, $f13 \n\t"
"madd.s $f8, $f8, $f5, $f7 \n\t"
"swc1 $f14, 20(%[out]) \n\t"
"lwc1 $f11, 28(%[in]) \n\t"
"mul.s $f12, $f3, $f13 \n\t"
"mul.s $f16, $f2, $f1 \n\t"
"msub.s $f16, $f16, %[gain], $f11 \n\t"
"sub.s $f0, $f16, $f12 \n\t"
"madd.s $f14, $f0, $f4, $f1 \n\t"
"madd.s $f14, $f14, $f5, $f13 \n\t"
"swc1 $f8, 24(%[out]) \n\t"
PTR_ADDIU "%[out], 32 \n\t"
PTR_ADDIU "%[in], 32 \n\t"
"addiu %[n], -8 \n\t"
"swc1 $f14, -4(%[out]) \n\t"
"bnez %[n], ff_acelp_apply_order_2_transfer_function_madd%= \n\t"
"swc1 $f1, 4(%[mem]) \n\t"
"swc1 $f0, 0(%[mem]) \n\t"
"ff_acelp_apply_order_2_transfer_function_end%=: \n\t"
: [out] "+r" (out),
[in] "+r" (in), [gain] "+f" (gain),
[n] "+r" (n), [mem] "+r" (mem)
: [zero_coeffs] "r" (zero_coeffs),
[pole_coeffs] "r" (pole_coeffs)
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
"$f6", "$f7", "$f8", "$f9", "$f10", "$f11",
"$f12", "$f13", "$f14", "$f15", "$f16", "memory"
);
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_acelp_filter_init_mips(ACELPFContext *c)
{
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->acelp_interpolatef = ff_acelp_interpolatef_mips;
c->acelp_apply_order_2_transfer_function = ff_acelp_apply_order_2_transfer_function_mips;
#endif
#endif
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* adaptive and fixed codebook vector operations for ACELP-based codecs
* optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/acelp_vectors.c
*/
#include "config.h"
#include "libavcodec/acelp_vectors.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ff_weighted_vector_sumf_mips(
float *out, const float *in_a, const float *in_b,
float weight_coeff_a, float weight_coeff_b, int length)
{
const float *a_end = in_a + length;
/* loop unrolled two times */
__asm__ volatile (
"blez %[length], ff_weighted_vector_sumf_end%= \n\t"
"ff_weighted_vector_sumf_madd%=: \n\t"
"lwc1 $f0, 0(%[in_a]) \n\t"
"lwc1 $f3, 4(%[in_a]) \n\t"
"lwc1 $f1, 0(%[in_b]) \n\t"
"lwc1 $f4, 4(%[in_b]) \n\t"
"mul.s $f2, %[weight_coeff_a], $f0 \n\t"
"mul.s $f5, %[weight_coeff_a], $f3 \n\t"
"madd.s $f2, $f2, %[weight_coeff_b], $f1 \n\t"
"madd.s $f5, $f5, %[weight_coeff_b], $f4 \n\t"
PTR_ADDIU "%[in_a],8 \n\t"
PTR_ADDIU "%[in_b],8 \n\t"
"swc1 $f2, 0(%[out]) \n\t"
"swc1 $f5, 4(%[out]) \n\t"
PTR_ADDIU "%[out], 8 \n\t"
"bne %[in_a], %[a_end], ff_weighted_vector_sumf_madd%= \n\t"
"ff_weighted_vector_sumf_end%=: \n\t"
: [out] "+r" (out), [in_a] "+r" (in_a), [in_b] "+r" (in_b)
: [weight_coeff_a] "f" (weight_coeff_a),
[weight_coeff_b] "f" (weight_coeff_b),
[length] "r" (length), [a_end]"r"(a_end)
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "memory"
);
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_acelp_vectors_init_mips(ACELPVContext *c)
{
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->weighted_vector_sumf = ff_weighted_vector_sumf_mips;
#endif
#endif
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/amrwbdec.c
*/
#include "libavutil/avutil.h"
#include "libavcodec/amrwbdata.h"
#include "amrwbdec_mips.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
void ff_hb_fir_filter_mips(float *out, const float fir_coef[HB_FIR_SIZE + 1],
float mem[HB_FIR_SIZE], const float *in)
{
int i;
float data[AMRWB_SFR_SIZE_16k + HB_FIR_SIZE]; // past and current samples
memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
memcpy(data + HB_FIR_SIZE, in, AMRWB_SFR_SIZE_16k * sizeof(float));
for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) {
float output;
float * p_data = (data+i);
/**
* inner loop is entirely unrolled and instructions are scheduled
* to minimize pipeline stall
*/
__asm__ volatile(
"mtc1 $zero, %[output] \n\t"
"lwc1 $f0, 0(%[p_data]) \n\t"
"lwc1 $f1, 0(%[fir_coef]) \n\t"
"lwc1 $f2, 4(%[p_data]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f3, 4(%[fir_coef]) \n\t"
"lwc1 $f4, 8(%[p_data]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f5, 8(%[fir_coef]) \n\t"
"lwc1 $f0, 12(%[p_data]) \n\t"
"lwc1 $f1, 12(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f2, 16(%[p_data]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f3, 16(%[fir_coef]) \n\t"
"lwc1 $f4, 20(%[p_data]) \n\t"
"lwc1 $f5, 20(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 24(%[p_data]) \n\t"
"lwc1 $f1, 24(%[fir_coef]) \n\t"
"lwc1 $f2, 28(%[p_data]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f3, 28(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f4, 32(%[p_data]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f5, 32(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f0, 36(%[p_data]) \n\t"
"lwc1 $f1, 36(%[fir_coef]) \n\t"
"lwc1 $f2, 40(%[p_data]) \n\t"
"lwc1 $f3, 40(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f4, 44(%[p_data]) \n\t"
"lwc1 $f5, 44(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 48(%[p_data]) \n\t"
"lwc1 $f1, 48(%[fir_coef]) \n\t"
"lwc1 $f2, 52(%[p_data]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f3, 52(%[fir_coef]) \n\t"
"lwc1 $f4, 56(%[p_data]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f5, 56(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 60(%[p_data]) \n\t"
"lwc1 $f1, 60(%[fir_coef]) \n\t"
"lwc1 $f2, 64(%[p_data]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f3, 64(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f4, 68(%[p_data]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f5, 68(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f0, 72(%[p_data]) \n\t"
"lwc1 $f1, 72(%[fir_coef]) \n\t"
"lwc1 $f2, 76(%[p_data]) \n\t"
"lwc1 $f3, 76(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f4, 80(%[p_data]) \n\t"
"lwc1 $f5, 80(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 84(%[p_data]) \n\t"
"lwc1 $f1, 84(%[fir_coef]) \n\t"
"lwc1 $f2, 88(%[p_data]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f3, 88(%[fir_coef]) \n\t"
"lwc1 $f4, 92(%[p_data]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f5, 92(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 96(%[p_data]) \n\t"
"lwc1 $f1, 96(%[fir_coef]) \n\t"
"lwc1 $f2, 100(%[p_data]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f3, 100(%[fir_coef]) \n\t"
"lwc1 $f4, 104(%[p_data]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f5, 104(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f0, 108(%[p_data]) \n\t"
"lwc1 $f1, 108(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"lwc1 $f2, 112(%[p_data]) \n\t"
"lwc1 $f3, 112(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
"lwc1 $f4, 116(%[p_data]) \n\t"
"lwc1 $f5, 116(%[fir_coef]) \n\t"
"lwc1 $f0, 120(%[p_data]) \n\t"
"madd.s %[output], %[output], $f2, $f3 \n\t"
"lwc1 $f1, 120(%[fir_coef]) \n\t"
"madd.s %[output], %[output], $f4, $f5 \n\t"
"madd.s %[output], %[output], $f0, $f1 \n\t"
: [output]"=&f"(output)
: [fir_coef]"r"(fir_coef), [p_data]"r"(p_data)
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "memory"
);
out[i] = output;
}
memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/amrwbdec.c
*/
#ifndef AVCODEC_MIPS_AMRWBDEC_MIPS_H
#define AVCODEC_MIPS_AMRWBDEC_MIPS_H
#include "config.h"
#if HAVE_MIPSFPU && HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
void ff_hb_fir_filter_mips(float *out, const float fir_coef[],
float mem[], const float *in);
#define hb_fir_filter ff_hb_fir_filter_mips
#endif
#endif
#endif /* AVCODEC_MIPS_AMRWBDEC_MIPS_H */

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2015 Parag Salasakar (parag.salasakar@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "blockdsp_mips.h"
#if HAVE_MSA
static av_cold void blockdsp_init_msa(BlockDSPContext *c)
{
c->clear_block = ff_clear_block_msa;
c->clear_blocks = ff_clear_blocks_msa;
c->fill_block_tab[0] = ff_fill_block16_msa;
c->fill_block_tab[1] = ff_fill_block8_msa;
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void blockdsp_init_mmi(BlockDSPContext *c)
{
c->clear_block = ff_clear_block_mmi;
c->clear_blocks = ff_clear_blocks_mmi;
c->fill_block_tab[0] = ff_fill_block16_mmi;
c->fill_block_tab[1] = ff_fill_block8_mmi;
}
#endif /* HAVE_MMI */
void ff_blockdsp_init_mips(BlockDSPContext *c)
{
#if HAVE_MMI
blockdsp_init_mmi(c);
#endif /* HAVE_MMI */
#if HAVE_MSA
blockdsp_init_msa(c);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2015 Parag Salasakar (parag.salasakar@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_BLOCKDSP_MIPS_H
#define AVCODEC_MIPS_BLOCKDSP_MIPS_H
#include "../mpegvideo.h"
void ff_fill_block16_msa(uint8_t *src, uint8_t val, ptrdiff_t stride, int height);
void ff_fill_block8_msa(uint8_t *src, uint8_t val, ptrdiff_t stride, int height);
void ff_clear_block_msa(int16_t *block);
void ff_clear_blocks_msa(int16_t *block);
void ff_fill_block16_mmi(uint8_t *block, uint8_t value, ptrdiff_t line_size, int h);
void ff_fill_block8_mmi(uint8_t *block, uint8_t value, ptrdiff_t line_size, int h);
void ff_clear_block_mmi(int16_t *block);
void ff_clear_blocks_mmi(int16_t *block);
#endif // #ifndef AVCODEC_MIPS_BLOCKDSP_MIPS_H

View File

@@ -0,0 +1,159 @@
/*
* Loongson SIMD optimized blockdsp
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "blockdsp_mips.h"
#include "libavutil/mips/mmiutils.h"
void ff_fill_block16_mmi(uint8_t *block, uint8_t value, ptrdiff_t line_size, int h)
{
double ftmp[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
"mtc1 %[value], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[block], 0x00)
PTR_ADDI "%[h], %[h], -0x01 \n\t"
MMI_SDC1(%[ftmp0], %[block], 0x08)
PTR_ADDU "%[block], %[block], %[line_size] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]),
RESTRICT_ASM_ALL64
[block]"+&r"(block), [h]"+&r"(h)
: [value]"r"(value), [line_size]"r"((mips_reg)line_size)
: "memory"
);
}
void ff_fill_block8_mmi(uint8_t *block, uint8_t value, ptrdiff_t line_size, int h)
{
double ftmp0;
DECLARE_VAR_ALL64;
__asm__ volatile (
"mtc1 %[value], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[block], 0x00)
PTR_ADDI "%[h], %[h], -0x01 \n\t"
PTR_ADDU "%[block], %[block], %[line_size] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp0),
RESTRICT_ASM_ALL64
[block]"+&r"(block), [h]"+&r"(h)
: [value]"r"(value), [line_size]"r"((mips_reg)line_size)
: "memory"
);
}
void ff_clear_block_mmi(int16_t *block)
{
double ftmp[2];
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x00)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x10)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x20)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x30)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x40)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x50)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x60)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x70)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1])
: [block]"r"(block)
: "memory"
);
}
void ff_clear_blocks_mmi(int16_t *block)
{
double ftmp[2];
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x00)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x10)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x20)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x30)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x40)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x50)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x60)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x70)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x80)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x90)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xa0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xb0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xc0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xd0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xe0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0xf0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x100)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x110)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x120)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x130)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x140)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x150)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x160)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x170)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x180)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x190)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1a0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1b0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1c0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1d0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1e0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x1f0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x200)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x210)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x220)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x230)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x240)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x250)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x260)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x270)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x280)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x290)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2a0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2b0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2c0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2d0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2e0)
MMI_SQC1(%[ftmp0], %[ftmp1], %[block], 0x2f0)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1])
: [block]"r"((uint64_t *)block)
: "memory"
);
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2015 Parag Salasakar (parag.salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "blockdsp_mips.h"
static void copy_8bit_value_width8_msa(uint8_t *src, uint8_t val,
int32_t src_stride, int32_t height)
{
int32_t cnt;
uint64_t dst0;
v16u8 val0;
val0 = (v16u8) __msa_fill_b(val);
dst0 = __msa_copy_u_d((v2i64) val0, 0);
for (cnt = (height >> 2); cnt--;) {
SD4(dst0, dst0, dst0, dst0, src, src_stride);
src += (4 * src_stride);
}
}
static void copy_8bit_value_width16_msa(uint8_t *src, uint8_t val,
int32_t src_stride, int32_t height)
{
int32_t cnt;
v16u8 val0;
val0 = (v16u8) __msa_fill_b(val);
for (cnt = (height >> 3); cnt--;) {
ST_UB8(val0, val0, val0, val0, val0, val0, val0, val0, src, src_stride);
src += (8 * src_stride);
}
}
static void memset_zero_16width_msa(uint8_t *src, int32_t stride,
int32_t height)
{
int8_t cnt;
v16u8 zero = { 0 };
for (cnt = (height / 2); cnt--;) {
ST_UB(zero, src);
src += stride;
ST_UB(zero, src);
src += stride;
}
}
void ff_fill_block16_msa(uint8_t *src, uint8_t val, ptrdiff_t stride, int height)
{
copy_8bit_value_width16_msa(src, val, stride, height);
}
void ff_fill_block8_msa(uint8_t *src, uint8_t val, ptrdiff_t stride, int height)
{
copy_8bit_value_width8_msa(src, val, stride, height);
}
void ff_clear_block_msa(int16_t *block)
{
memset_zero_16width_msa((uint8_t *) block, 16, 8);
}
void ff_clear_blocks_msa(int16_t *block)
{
memset_zero_16width_msa((uint8_t *) block, 16, 8 * 6);
}

119
externals/ffmpeg/libavcodec/mips/cabac.h vendored Executable file
View File

@@ -0,0 +1,119 @@
/*
* Loongson SIMD optimized h264chroma
*
* Copyright (c) 2018 Loongson Technology Corporation Limited
* Copyright (c) 2018 Shiyou Yin <yinshiyou-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_CABAC_H
#define AVCODEC_MIPS_CABAC_H
#include "libavcodec/cabac.h"
#include "libavutil/mips/mmiutils.h"
#include "config.h"
#define get_cabac_inline get_cabac_inline_mips
static av_always_inline int get_cabac_inline_mips(CABACContext *c,
uint8_t * const state){
mips_reg tmp0, tmp1, tmp2, bit;
__asm__ volatile (
"lbu %[bit], 0(%[state]) \n\t"
"and %[tmp0], %[c_range], 0xC0 \n\t"
PTR_ADDU "%[tmp0], %[tmp0], %[tmp0] \n\t"
PTR_ADDU "%[tmp0], %[tmp0], %[tables] \n\t"
PTR_ADDU "%[tmp0], %[tmp0], %[bit] \n\t"
/* tmp1: RangeLPS */
"lbu %[tmp1], %[lps_off](%[tmp0]) \n\t"
PTR_SUBU "%[c_range], %[c_range], %[tmp1] \n\t"
PTR_SLL "%[tmp0], %[c_range], 0x11 \n\t"
PTR_SUBU "%[tmp0], %[tmp0], %[c_low] \n\t"
/* tmp2: lps_mask */
PTR_SRA "%[tmp2], %[tmp0], 0x1F \n\t"
/* If tmp0 < 0, lps_mask == 0xffffffff*/
/* If tmp0 >= 0, lps_mask == 0x00000000*/
"beqz %[tmp2], 1f \n\t"
PTR_SLL "%[tmp0], %[c_range], 0x11 \n\t"
PTR_SUBU "%[c_low], %[c_low], %[tmp0] \n\t"
PTR_SUBU "%[tmp0], %[tmp1], %[c_range] \n\t"
PTR_ADDU "%[c_range], %[c_range], %[tmp0] \n\t"
"xor %[bit], %[bit], %[tmp2] \n\t"
"1: \n\t"
/* tmp1: *state */
PTR_ADDU "%[tmp0], %[tables], %[bit] \n\t"
"lbu %[tmp1], %[mlps_off](%[tmp0]) \n\t"
/* tmp2: lps_mask */
PTR_ADDU "%[tmp0], %[tables], %[c_range] \n\t"
"lbu %[tmp2], %[norm_off](%[tmp0]) \n\t"
"sb %[tmp1], 0(%[state]) \n\t"
"and %[bit], %[bit], 0x01 \n\t"
PTR_SLL "%[c_range], %[c_range], %[tmp2] \n\t"
PTR_SLL "%[c_low], %[c_low], %[tmp2] \n\t"
"and %[tmp0], %[c_low], %[cabac_mask] \n\t"
"bnez %[tmp0], 1f \n\t"
PTR_ADDIU "%[tmp0], %[c_low], -0x01 \n\t"
"xor %[tmp0], %[c_low], %[tmp0] \n\t"
PTR_SRA "%[tmp0], %[tmp0], 0x0f \n\t"
PTR_ADDU "%[tmp0], %[tmp0], %[tables] \n\t"
"lbu %[tmp2], %[norm_off](%[tmp0]) \n\t"
#if CABAC_BITS == 16
"lbu %[tmp0], 0(%[c_bytestream]) \n\t"
"lbu %[tmp1], 1(%[c_bytestream]) \n\t"
PTR_SLL "%[tmp0], %[tmp0], 0x09 \n\t"
PTR_SLL "%[tmp1], %[tmp1], 0x01 \n\t"
PTR_ADDU "%[tmp0], %[tmp0], %[tmp1] \n\t"
#else
"lbu %[tmp0], 0(%[c_bytestream]) \n\t"
PTR_SLL "%[tmp0], %[tmp0], 0x01 \n\t"
#endif
PTR_SUBU "%[tmp0], %[tmp0], %[cabac_mask] \n\t"
"li %[tmp1], 0x07 \n\t"
PTR_SUBU "%[tmp1], %[tmp1], %[tmp2] \n\t"
PTR_SLL "%[tmp0], %[tmp0], %[tmp1] \n\t"
PTR_ADDU "%[c_low], %[c_low], %[tmp0] \n\t"
#if !UNCHECKED_BITSTREAM_READER
"bge %[c_bytestream], %[c_bytestream_end], 1f \n\t"
#endif
PTR_ADDIU "%[c_bytestream], %[c_bytestream], 0X02 \n\t"
"1: \n\t"
: [bit]"=&r"(bit), [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2),
[c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
[c_bytestream]"+&r"(c->bytestream)
: [state]"r"(state), [tables]"r"(ff_h264_cabac_tables),
#if !UNCHECKED_BITSTREAM_READER
[c_bytestream_end]"r"(c->bytestream_end),
#endif
[lps_off]"i"(H264_LPS_RANGE_OFFSET),
[mlps_off]"i"(H264_MLPS_STATE_OFFSET + 128),
[norm_off]"i"(H264_NORM_SHIFT_OFFSET),
[cabac_mask]"i"(CABAC_MASK)
: "memory"
);
return bit;
}
#endif /* AVCODEC_MIPS_CABAC_H */

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* various filters for CELP-based codecs optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/celp_filters.c
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/common.h"
#include "libavcodec/celp_filters.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ff_celp_lp_synthesis_filterf_mips(float *out,
const float *filter_coeffs,
const float* in, int buffer_length,
int filter_length)
{
int i,n;
float out0, out1, out2, out3;
float old_out0, old_out1, old_out2, old_out3;
float a,b,c;
const float *p_filter_coeffs;
float *p_out;
a = filter_coeffs[0];
b = filter_coeffs[1];
c = filter_coeffs[2];
b -= filter_coeffs[0] * filter_coeffs[0];
c -= filter_coeffs[1] * filter_coeffs[0];
c -= filter_coeffs[0] * b;
old_out0 = out[-4];
old_out1 = out[-3];
old_out2 = out[-2];
old_out3 = out[-1];
for (n = 0; n <= buffer_length - 4; n+=4) {
p_filter_coeffs = filter_coeffs;
p_out = out;
out0 = in[0];
out1 = in[1];
out2 = in[2];
out3 = in[3];
__asm__ volatile(
"lwc1 $f2, 8(%[filter_coeffs]) \n\t"
"lwc1 $f1, 4(%[filter_coeffs]) \n\t"
"lwc1 $f0, 0(%[filter_coeffs]) \n\t"
"nmsub.s %[out0], %[out0], $f2, %[old_out1] \n\t"
"nmsub.s %[out1], %[out1], $f2, %[old_out2] \n\t"
"nmsub.s %[out2], %[out2], $f2, %[old_out3] \n\t"
"lwc1 $f3, 12(%[filter_coeffs]) \n\t"
"nmsub.s %[out0], %[out0], $f1, %[old_out2] \n\t"
"nmsub.s %[out1], %[out1], $f1, %[old_out3] \n\t"
"nmsub.s %[out2], %[out2], $f3, %[old_out2] \n\t"
"nmsub.s %[out0], %[out0], $f0, %[old_out3] \n\t"
"nmsub.s %[out3], %[out3], $f3, %[old_out3] \n\t"
"nmsub.s %[out1], %[out1], $f3, %[old_out1] \n\t"
"nmsub.s %[out0], %[out0], $f3, %[old_out0] \n\t"
: [out0]"+f"(out0), [out1]"+f"(out1),
[out2]"+f"(out2), [out3]"+f"(out3)
: [old_out0]"f"(old_out0), [old_out1]"f"(old_out1),
[old_out2]"f"(old_out2), [old_out3]"f"(old_out3),
[filter_coeffs]"r"(filter_coeffs)
: "$f0", "$f1", "$f2", "$f3", "$f4", "memory"
);
for (i = 5; i <= filter_length; i += 2) {
__asm__ volatile(
"lwc1 %[old_out3], -20(%[p_out]) \n\t"
"lwc1 $f5, 16(%[p_filter_coeffs]) \n\t"
PTR_ADDIU "%[p_out], -8 \n\t"
PTR_ADDIU "%[p_filter_coeffs], 8 \n\t"
"nmsub.s %[out1], %[out1], $f5, %[old_out0] \n\t"
"nmsub.s %[out3], %[out3], $f5, %[old_out2] \n\t"
"lwc1 $f4, 12(%[p_filter_coeffs]) \n\t"
"lwc1 %[old_out2], -16(%[p_out]) \n\t"
"nmsub.s %[out0], %[out0], $f5, %[old_out3] \n\t"
"nmsub.s %[out2], %[out2], $f5, %[old_out1] \n\t"
"nmsub.s %[out1], %[out1], $f4, %[old_out3] \n\t"
"nmsub.s %[out3], %[out3], $f4, %[old_out1] \n\t"
"mov.s %[old_out1], %[old_out3] \n\t"
"nmsub.s %[out0], %[out0], $f4, %[old_out2] \n\t"
"nmsub.s %[out2], %[out2], $f4, %[old_out0] \n\t"
: [out0]"+f"(out0), [out1]"+f"(out1),
[out2]"+f"(out2), [out3]"+f"(out3), [old_out0]"+f"(old_out0),
[old_out1]"+f"(old_out1), [old_out2]"+f"(old_out2),
[old_out3]"+f"(old_out3),[p_filter_coeffs]"+r"(p_filter_coeffs),
[p_out]"+r"(p_out)
:
: "$f4", "$f5", "memory"
);
FFSWAP(float, old_out0, old_out2);
}
__asm__ volatile(
"nmsub.s %[out3], %[out3], %[a], %[out2] \n\t"
"nmsub.s %[out2], %[out2], %[a], %[out1] \n\t"
"nmsub.s %[out3], %[out3], %[b], %[out1] \n\t"
"nmsub.s %[out1], %[out1], %[a], %[out0] \n\t"
"nmsub.s %[out2], %[out2], %[b], %[out0] \n\t"
"nmsub.s %[out3], %[out3], %[c], %[out0] \n\t"
: [out0]"+f"(out0), [out1]"+f"(out1),
[out2]"+f"(out2), [out3]"+f"(out3)
: [a]"f"(a), [b]"f"(b), [c]"f"(c)
);
out[0] = out0;
out[1] = out1;
out[2] = out2;
out[3] = out3;
old_out0 = out0;
old_out1 = out1;
old_out2 = out2;
old_out3 = out3;
out += 4;
in += 4;
}
out -= n;
in -= n;
for (; n < buffer_length; n++) {
float out_val, out_val_i, fc_val;
p_filter_coeffs = filter_coeffs;
p_out = &out[n];
out_val = in[n];
for (i = 1; i <= filter_length; i++) {
__asm__ volatile(
"lwc1 %[fc_val], 0(%[p_filter_coeffs]) \n\t"
"lwc1 %[out_val_i], -4(%[p_out]) \n\t"
PTR_ADDIU "%[p_filter_coeffs], 4 \n\t"
PTR_ADDIU "%[p_out], -4 \n\t"
"nmsub.s %[out_val], %[out_val], %[fc_val], %[out_val_i] \n\t"
: [fc_val]"=&f"(fc_val), [out_val]"+f"(out_val),
[out_val_i]"=&f"(out_val_i), [p_out]"+r"(p_out),
[p_filter_coeffs]"+r"(p_filter_coeffs)
:
: "memory"
);
}
out[n] = out_val;
}
}
static void ff_celp_lp_zero_synthesis_filterf_mips(float *out,
const float *filter_coeffs,
const float *in, int buffer_length,
int filter_length)
{
int i,n;
float sum_out8, sum_out7, sum_out6, sum_out5, sum_out4, fc_val;
float sum_out3, sum_out2, sum_out1;
const float *p_filter_coeffs, *p_in;
for (n = 0; n < buffer_length; n+=8) {
p_in = &in[n];
p_filter_coeffs = filter_coeffs;
sum_out8 = in[n+7];
sum_out7 = in[n+6];
sum_out6 = in[n+5];
sum_out5 = in[n+4];
sum_out4 = in[n+3];
sum_out3 = in[n+2];
sum_out2 = in[n+1];
sum_out1 = in[n];
i = filter_length;
/* i is always greater than 0
* outer loop is unrolled eight times so there is less memory access
* inner loop is unrolled two times
*/
__asm__ volatile(
"filt_lp_inner%=: \n\t"
"lwc1 %[fc_val], 0(%[p_filter_coeffs]) \n\t"
"lwc1 $f7, 6*4(%[p_in]) \n\t"
"lwc1 $f6, 5*4(%[p_in]) \n\t"
"lwc1 $f5, 4*4(%[p_in]) \n\t"
"lwc1 $f4, 3*4(%[p_in]) \n\t"
"lwc1 $f3, 2*4(%[p_in]) \n\t"
"lwc1 $f2, 4(%[p_in]) \n\t"
"lwc1 $f1, 0(%[p_in]) \n\t"
"lwc1 $f0, -4(%[p_in]) \n\t"
"addiu %[i], -2 \n\t"
"madd.s %[sum_out8], %[sum_out8], %[fc_val], $f7 \n\t"
"madd.s %[sum_out7], %[sum_out7], %[fc_val], $f6 \n\t"
"madd.s %[sum_out6], %[sum_out6], %[fc_val], $f5 \n\t"
"madd.s %[sum_out5], %[sum_out5], %[fc_val], $f4 \n\t"
"madd.s %[sum_out4], %[sum_out4], %[fc_val], $f3 \n\t"
"madd.s %[sum_out3], %[sum_out3], %[fc_val], $f2 \n\t"
"madd.s %[sum_out2], %[sum_out2], %[fc_val], $f1 \n\t"
"madd.s %[sum_out1], %[sum_out1], %[fc_val], $f0 \n\t"
"lwc1 %[fc_val], 4(%[p_filter_coeffs]) \n\t"
"lwc1 $f7, -8(%[p_in]) \n\t"
PTR_ADDIU "%[p_filter_coeffs], 8 \n\t"
PTR_ADDIU "%[p_in], -8 \n\t"
"madd.s %[sum_out8], %[sum_out8], %[fc_val], $f6 \n\t"
"madd.s %[sum_out7], %[sum_out7], %[fc_val], $f5 \n\t"
"madd.s %[sum_out6], %[sum_out6], %[fc_val], $f4 \n\t"
"madd.s %[sum_out5], %[sum_out5], %[fc_val], $f3 \n\t"
"madd.s %[sum_out4], %[sum_out4], %[fc_val], $f2 \n\t"
"madd.s %[sum_out3], %[sum_out3], %[fc_val], $f1 \n\t"
"madd.s %[sum_out2], %[sum_out2], %[fc_val], $f0 \n\t"
"madd.s %[sum_out1], %[sum_out1], %[fc_val], $f7 \n\t"
"bgtz %[i], filt_lp_inner%= \n\t"
: [sum_out8]"+f"(sum_out8), [sum_out7]"+f"(sum_out7),
[sum_out6]"+f"(sum_out6), [sum_out5]"+f"(sum_out5),
[sum_out4]"+f"(sum_out4), [sum_out3]"+f"(sum_out3),
[sum_out2]"+f"(sum_out2), [sum_out1]"+f"(sum_out1),
[fc_val]"=&f"(fc_val), [p_filter_coeffs]"+r"(p_filter_coeffs),
[p_in]"+r"(p_in), [i]"+r"(i)
:
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "memory"
);
out[n+7] = sum_out8;
out[n+6] = sum_out7;
out[n+5] = sum_out6;
out[n+4] = sum_out5;
out[n+3] = sum_out4;
out[n+2] = sum_out3;
out[n+1] = sum_out2;
out[n] = sum_out1;
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_celp_filter_init_mips(CELPFContext *c)
{
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->celp_lp_synthesis_filterf = ff_celp_lp_synthesis_filterf_mips;
c->celp_lp_zero_synthesis_filterf = ff_celp_lp_zero_synthesis_filterf_mips;
#endif
#endif
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* Math operations optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/celp_math.c
*/
#include "config.h"
#include "libavcodec/celp_math.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static float ff_dot_productf_mips(const float* a, const float* b,
int length)
{
float sum;
const float* a_end = a + length;
__asm__ volatile (
"mtc1 $zero, %[sum] \n\t"
"blez %[length], ff_dot_productf_end%= \n\t"
"ff_dot_productf_madd%=: \n\t"
"lwc1 $f2, 0(%[a]) \n\t"
"lwc1 $f1, 0(%[b]) \n\t"
PTR_ADDIU "%[a], %[a], 4 \n\t"
PTR_ADDIU "%[b], %[b], 4 \n\t"
"madd.s %[sum], %[sum], $f1, $f2 \n\t"
"bne %[a], %[a_end], ff_dot_productf_madd%= \n\t"
"ff_dot_productf_end%=: \n\t"
: [sum] "=&f" (sum), [a] "+r" (a), [b] "+r" (b)
: [a_end]"r"(a_end), [length] "r" (length)
: "$f1", "$f2", "memory"
);
return sum;
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_celp_math_init_mips(CELPMContext *c)
{
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
c->dot_productf = ff_dot_productf_mips;
#endif
#endif
}

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Bojan Zivkovic (bojan@mips.com)
*
* Compute antialias function optimised for MIPS fixed-point architecture
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/mpegaudiodec.c
*/
#ifndef AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H
#define AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H
#if HAVE_INLINE_ASM
static void compute_antialias_mips_fixed(MPADecodeContext *s,
GranuleDef *g)
{
int32_t *ptr, *csa;
int n, i;
int MAX_lo = 0xffffffff;
/* we antialias only "long" bands */
if (g->block_type == 2) {
if (!g->switch_point)
return;
/* XXX: check this for 8000Hz case */
n = 1;
} else {
n = SBLIMIT - 1;
}
ptr = g->sb_hybrid + 18;
for(i = n;i > 0;i--) {
int tmp0, tmp1, tmp2, tmp00, tmp11;
int temp_reg1, temp_reg2, temp_reg3, temp_reg4, temp_reg5, temp_reg6;
csa = &csa_table[0][0];
/**
* instructions are scheduled to minimize pipeline stall.
*/
__asm__ volatile (
"lw %[tmp0], -1*4(%[ptr]) \n\t"
"lw %[tmp1], 0*4(%[ptr]) \n\t"
"lw %[temp_reg1], 0*4(%[csa]) \n\t"
"lw %[temp_reg2], 2*4(%[csa]) \n\t"
"add %[tmp2], %[tmp0], %[tmp1] \n\t"
"lw %[temp_reg3], 3*4(%[csa]) \n\t"
"mult $ac0, %[tmp2], %[temp_reg1] \n\t"
"mult $ac1, %[tmp2], %[temp_reg1] \n\t"
"lw %[tmp00], -2*4(%[ptr]) \n\t"
"lw %[tmp11], 1*4(%[ptr]) \n\t"
"lw %[temp_reg4], 4*4(%[csa]) \n\t"
"mtlo %[MAX_lo], $ac0 \n\t"
"mtlo $zero, $ac1 \n\t"
"msub $ac0, %[tmp1], %[temp_reg2] \n\t"
"madd $ac1, %[tmp0], %[temp_reg3] \n\t"
"add %[tmp2], %[tmp00], %[tmp11] \n\t"
"lw %[temp_reg5], 6*4(%[csa]) \n\t"
"mult $ac2, %[tmp2], %[temp_reg4] \n\t"
"mult $ac3, %[tmp2], %[temp_reg4] \n\t"
"mfhi %[temp_reg1], $ac0 \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"lw %[temp_reg6], 7*4(%[csa]) \n\t"
"mtlo %[MAX_lo], $ac2 \n\t"
"msub $ac2, %[tmp11], %[temp_reg5] \n\t"
"mtlo $zero, $ac3 \n\t"
"madd $ac3, %[tmp00], %[temp_reg6] \n\t"
"sll %[temp_reg1], %[temp_reg1], 2 \n\t"
"sw %[temp_reg1], -1*4(%[ptr]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"sll %[temp_reg2], %[temp_reg2], 2 \n\t"
"mfhi %[temp_reg5], $ac3 \n\t"
"sw %[temp_reg2], 0*4(%[ptr]) \n\t"
"lw %[tmp0], -3*4(%[ptr]) \n\t"
"lw %[tmp1], 2*4(%[ptr]) \n\t"
"lw %[temp_reg1], 8*4(%[csa]) \n\t"
"sll %[temp_reg4], %[temp_reg4], 2 \n\t"
"add %[tmp2], %[tmp0], %[tmp1] \n\t"
"sll %[temp_reg5], %[temp_reg5], 2 \n\t"
"mult $ac0, %[tmp2], %[temp_reg1] \n\t"
"mult $ac1, %[tmp2], %[temp_reg1] \n\t"
"sw %[temp_reg4], -2*4(%[ptr]) \n\t"
"sw %[temp_reg5], 1*4(%[ptr]) \n\t"
"lw %[temp_reg2], 10*4(%[csa]) \n\t"
"mtlo %[MAX_lo], $ac0 \n\t"
"lw %[temp_reg3], 11*4(%[csa]) \n\t"
"msub $ac0, %[tmp1], %[temp_reg2] \n\t"
"mtlo $zero, $ac1 \n\t"
"madd $ac1, %[tmp0], %[temp_reg3] \n\t"
"lw %[tmp00], -4*4(%[ptr]) \n\t"
"lw %[tmp11], 3*4(%[ptr]) \n\t"
"mfhi %[temp_reg1], $ac0 \n\t"
"lw %[temp_reg4], 12*4(%[csa]) \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"add %[tmp2], %[tmp00], %[tmp11] \n\t"
"mult $ac2, %[tmp2], %[temp_reg4] \n\t"
"mult $ac3, %[tmp2], %[temp_reg4] \n\t"
"lw %[temp_reg5], 14*4(%[csa]) \n\t"
"lw %[temp_reg6], 15*4(%[csa]) \n\t"
"sll %[temp_reg1], %[temp_reg1], 2 \n\t"
"mtlo %[MAX_lo], $ac2 \n\t"
"msub $ac2, %[tmp11], %[temp_reg5] \n\t"
"mtlo $zero, $ac3 \n\t"
"madd $ac3, %[tmp00], %[temp_reg6] \n\t"
"sll %[temp_reg2], %[temp_reg2], 2 \n\t"
"sw %[temp_reg1], -3*4(%[ptr]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"sw %[temp_reg2], 2*4(%[ptr]) \n\t"
"mfhi %[temp_reg5], $ac3 \n\t"
"lw %[tmp0], -5*4(%[ptr]) \n\t"
"lw %[tmp1], 4*4(%[ptr]) \n\t"
"lw %[temp_reg1], 16*4(%[csa]) \n\t"
"lw %[temp_reg2], 18*4(%[csa]) \n\t"
"add %[tmp2], %[tmp0], %[tmp1] \n\t"
"lw %[temp_reg3], 19*4(%[csa]) \n\t"
"mult $ac0, %[tmp2], %[temp_reg1] \n\t"
"mult $ac1, %[tmp2], %[temp_reg1] \n\t"
"sll %[temp_reg4], %[temp_reg4], 2 \n\t"
"sll %[temp_reg5], %[temp_reg5], 2 \n\t"
"sw %[temp_reg4], -4*4(%[ptr]) \n\t"
"mtlo %[MAX_lo], $ac0 \n\t"
"msub $ac0, %[tmp1], %[temp_reg2] \n\t"
"mtlo $zero, $ac1 \n\t"
"madd $ac1, %[tmp0], %[temp_reg3] \n\t"
"sw %[temp_reg5], 3*4(%[ptr]) \n\t"
"lw %[tmp00], -6*4(%[ptr]) \n\t"
"mfhi %[temp_reg1], $ac0 \n\t"
"lw %[tmp11], 5*4(%[ptr]) \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"lw %[temp_reg4], 20*4(%[csa]) \n\t"
"add %[tmp2], %[tmp00], %[tmp11] \n\t"
"lw %[temp_reg5], 22*4(%[csa]) \n\t"
"mult $ac2, %[tmp2], %[temp_reg4] \n\t"
"mult $ac3, %[tmp2], %[temp_reg4] \n\t"
"lw %[temp_reg6], 23*4(%[csa]) \n\t"
"sll %[temp_reg1], %[temp_reg1], 2 \n\t"
"sll %[temp_reg2], %[temp_reg2], 2 \n\t"
"mtlo %[MAX_lo], $ac2 \n\t"
"msub $ac2, %[tmp11], %[temp_reg5] \n\t"
"mtlo $zero, $ac3 \n\t"
"madd $ac3, %[tmp00], %[temp_reg6] \n\t"
"sw %[temp_reg1], -5*4(%[ptr]) \n\t"
"sw %[temp_reg2], 4*4(%[ptr]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"lw %[tmp0], -7*4(%[ptr]) \n\t"
"mfhi %[temp_reg5], $ac3 \n\t"
"lw %[tmp1], 6*4(%[ptr]) \n\t"
"lw %[temp_reg1], 24*4(%[csa]) \n\t"
"lw %[temp_reg2], 26*4(%[csa]) \n\t"
"add %[tmp2], %[tmp0], %[tmp1] \n\t"
"lw %[temp_reg3], 27*4(%[csa]) \n\t"
"mult $ac0, %[tmp2], %[temp_reg1] \n\t"
"mult $ac1, %[tmp2], %[temp_reg1] \n\t"
"sll %[temp_reg4], %[temp_reg4], 2 \n\t"
"sll %[temp_reg5], %[temp_reg5], 2 \n\t"
"sw %[temp_reg4], -6*4(%[ptr]) \n\t"
"mtlo %[MAX_lo], $ac0 \n\t"
"msub $ac0, %[tmp1], %[temp_reg2] \n\t"
"mtlo $zero, $ac1 \n\t"
"madd $ac1, %[tmp0], %[temp_reg3] \n\t"
"sw %[temp_reg5], 5*4(%[ptr]) \n\t"
"lw %[tmp00], -8*4(%[ptr]) \n\t"
"mfhi %[temp_reg1], $ac0 \n\t"
"lw %[tmp11], 7*4(%[ptr]) \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"lw %[temp_reg4], 28*4(%[csa]) \n\t"
"add %[tmp2], %[tmp00], %[tmp11] \n\t"
"lw %[temp_reg5], 30*4(%[csa]) \n\t"
"mult $ac2, %[tmp2], %[temp_reg4] \n\t"
"mult $ac3, %[tmp2], %[temp_reg4] \n\t"
"lw %[temp_reg6], 31*4(%[csa]) \n\t"
"sll %[temp_reg1], %[temp_reg1], 2 \n\t"
"sll %[temp_reg2], %[temp_reg2], 2 \n\t"
"mtlo %[MAX_lo], $ac2 \n\t"
"msub $ac2, %[tmp11], %[temp_reg5] \n\t"
"mtlo $zero, $ac3 \n\t"
"madd $ac3, %[tmp00], %[temp_reg6] \n\t"
"sw %[temp_reg1], -7*4(%[ptr]) \n\t"
"sw %[temp_reg2], 6*4(%[ptr]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"mfhi %[temp_reg5], $ac3 \n\t"
"sll %[temp_reg4], %[temp_reg4], 2 \n\t"
"sll %[temp_reg5], %[temp_reg5], 2 \n\t"
"sw %[temp_reg4], -8*4(%[ptr]) \n\t"
"sw %[temp_reg5], 7*4(%[ptr]) \n\t"
: [tmp0] "=&r" (tmp0), [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2),
[tmp00] "=&r" (tmp00), [tmp11] "=&r" (tmp11),
[temp_reg1] "=&r" (temp_reg1), [temp_reg2] "=&r" (temp_reg2),
[temp_reg3] "=&r" (temp_reg3), [temp_reg4] "=&r" (temp_reg4),
[temp_reg5] "=&r" (temp_reg5), [temp_reg6] "=&r" (temp_reg6)
: [csa] "r" (csa), [ptr] "r" (ptr),
[MAX_lo] "r" (MAX_lo)
: "memory", "hi", "lo", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo",
"$ac3hi", "$ac3lo"
);
ptr += 18;
}
}
#define compute_antialias compute_antialias_mips_fixed
#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H */

View File

@@ -0,0 +1,186 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Bojan Zivkovic (bojan@mips.com)
*
* Compute antialias function optimised for MIPS floating-point architecture
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/mpegaudiodec.c
*/
#ifndef AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H
#define AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void compute_antialias_mips_float(MPADecodeContext *s,
GranuleDef *g)
{
float *ptr, *ptr_end;
float *csa = &csa_table[0][0];
/* temporary variables */
float in1, in2, in3, in4, in5, in6, in7, in8;
float out1, out2, out3, out4;
ptr = g->sb_hybrid + 18;
/* we antialias only "long" bands */
if (g->block_type == 2) {
if (!g->switch_point)
return;
/* XXX: check this for 8000Hz case */
ptr_end = ptr + 18;
} else {
ptr_end = ptr + 558;
}
/**
* instructions are scheduled to minimize pipeline stall.
*/
__asm__ volatile (
"compute_antialias_float_loop%=: \t\n"
"lwc1 %[in1], -1*4(%[ptr]) \t\n"
"lwc1 %[in2], 0(%[csa]) \t\n"
"lwc1 %[in3], 1*4(%[csa]) \t\n"
"lwc1 %[in4], 0(%[ptr]) \t\n"
"lwc1 %[in5], -2*4(%[ptr]) \t\n"
"lwc1 %[in6], 4*4(%[csa]) \t\n"
"mul.s %[out1], %[in1], %[in2] \t\n"
"mul.s %[out2], %[in1], %[in3] \t\n"
"lwc1 %[in7], 5*4(%[csa]) \t\n"
"lwc1 %[in8], 1*4(%[ptr]) \t\n"
"nmsub.s %[out1], %[out1], %[in3], %[in4] \t\n"
"madd.s %[out2], %[out2], %[in2], %[in4] \t\n"
"mul.s %[out3], %[in5], %[in6] \t\n"
"mul.s %[out4], %[in5], %[in7] \t\n"
"lwc1 %[in1], -3*4(%[ptr]) \t\n"
"swc1 %[out1], -1*4(%[ptr]) \t\n"
"swc1 %[out2], 0(%[ptr]) \t\n"
"nmsub.s %[out3], %[out3], %[in7], %[in8] \t\n"
"madd.s %[out4], %[out4], %[in6], %[in8] \t\n"
"lwc1 %[in2], 8*4(%[csa]) \t\n"
"swc1 %[out3], -2*4(%[ptr]) \t\n"
"swc1 %[out4], 1*4(%[ptr]) \t\n"
"lwc1 %[in3], 9*4(%[csa]) \t\n"
"lwc1 %[in4], 2*4(%[ptr]) \t\n"
"mul.s %[out1], %[in1], %[in2] \t\n"
"lwc1 %[in5], -4*4(%[ptr]) \t\n"
"lwc1 %[in6], 12*4(%[csa]) \t\n"
"mul.s %[out2], %[in1], %[in3] \t\n"
"lwc1 %[in7], 13*4(%[csa]) \t\n"
"nmsub.s %[out1], %[out1], %[in3], %[in4] \t\n"
"lwc1 %[in8], 3*4(%[ptr]) \t\n"
"mul.s %[out3], %[in5], %[in6] \t\n"
"madd.s %[out2], %[out2], %[in2], %[in4] \t\n"
"mul.s %[out4], %[in5], %[in7] \t\n"
"swc1 %[out1], -3*4(%[ptr]) \t\n"
"lwc1 %[in1], -5*4(%[ptr]) \t\n"
"nmsub.s %[out3], %[out3], %[in7], %[in8] \t\n"
"swc1 %[out2], 2*4(%[ptr]) \t\n"
"madd.s %[out4], %[out4], %[in6], %[in8] \t\n"
"lwc1 %[in2], 16*4(%[csa]) \t\n"
"lwc1 %[in3], 17*4(%[csa]) \t\n"
"swc1 %[out3], -4*4(%[ptr]) \t\n"
"lwc1 %[in4], 4*4(%[ptr]) \t\n"
"swc1 %[out4], 3*4(%[ptr]) \t\n"
"mul.s %[out1], %[in1], %[in2] \t\n"
"mul.s %[out2], %[in1], %[in3] \t\n"
"lwc1 %[in5], -6*4(%[ptr]) \t\n"
"lwc1 %[in6], 20*4(%[csa]) \t\n"
"lwc1 %[in7], 21*4(%[csa]) \t\n"
"nmsub.s %[out1], %[out1], %[in3], %[in4] \t\n"
"madd.s %[out2], %[out2], %[in2], %[in4] \t\n"
"lwc1 %[in8], 5*4(%[ptr]) \t\n"
"mul.s %[out3], %[in5], %[in6] \t\n"
"mul.s %[out4], %[in5], %[in7] \t\n"
"swc1 %[out1], -5*4(%[ptr]) \t\n"
"swc1 %[out2], 4*4(%[ptr]) \t\n"
"lwc1 %[in1], -7*4(%[ptr]) \t\n"
"nmsub.s %[out3], %[out3], %[in7], %[in8] \t\n"
"madd.s %[out4], %[out4], %[in6], %[in8] \t\n"
"lwc1 %[in2], 24*4(%[csa]) \t\n"
"lwc1 %[in3], 25*4(%[csa]) \t\n"
"lwc1 %[in4], 6*4(%[ptr]) \t\n"
"swc1 %[out3], -6*4(%[ptr]) \t\n"
"swc1 %[out4], 5*4(%[ptr]) \t\n"
"mul.s %[out1], %[in1], %[in2] \t\n"
"lwc1 %[in5], -8*4(%[ptr]) \t\n"
"mul.s %[out2], %[in1], %[in3] \t\n"
"lwc1 %[in6], 28*4(%[csa]) \t\n"
"lwc1 %[in7], 29*4(%[csa]) \t\n"
"nmsub.s %[out1], %[out1], %[in3], %[in4] \t\n"
"lwc1 %[in8], 7*4(%[ptr]) \t\n"
"madd.s %[out2], %[out2], %[in2], %[in4] \t\n"
"mul.s %[out3], %[in5], %[in6] \t\n"
"mul.s %[out4], %[in5], %[in7] \t\n"
"swc1 %[out1], -7*4(%[ptr]) \t\n"
"swc1 %[out2], 6*4(%[ptr]) \t\n"
PTR_ADDIU "%[ptr],%[ptr], 72 \t\n"
"nmsub.s %[out3], %[out3], %[in7], %[in8] \t\n"
"madd.s %[out4], %[out4], %[in6], %[in8] \t\n"
"swc1 %[out3], -26*4(%[ptr]) \t\n"
"swc1 %[out4], -11*4(%[ptr]) \t\n"
"bne %[ptr], %[ptr_end], compute_antialias_float_loop%= \t\n"
: [ptr] "+r" (ptr),
[in1] "=&f" (in1), [in2] "=&f" (in2),
[in3] "=&f" (in3), [in4] "=&f" (in4),
[in5] "=&f" (in5), [in6] "=&f" (in6),
[in7] "=&f" (in7), [in8] "=&f" (in8),
[out1] "=&f" (out1), [out2] "=&f" (out2),
[out3] "=&f" (out3), [out4] "=&f" (out4)
: [csa] "r" (csa), [ptr_end] "r" (ptr_end)
: "memory"
);
}
#define compute_antialias compute_antialias_mips_float
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H */

68
externals/ffmpeg/libavcodec/mips/constants.c vendored Executable file
View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/mem.h"
#include "constants.h"
DECLARE_ALIGNED(8, const uint64_t, ff_pw_1) = {0x0001000100010001ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_2) = {0x0002000200020002ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_3) = {0x0003000300030003ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_4) = {0x0004000400040004ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_5) = {0x0005000500050005ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_6) = {0x0006000600060006ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_8) = {0x0008000800080008ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_9) = {0x0009000900090009ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_10) = {0x000A000A000A000AULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_12) = {0x000C000C000C000CULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_15) = {0x000F000F000F000FULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_16) = {0x0010001000100010ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_17) = {0x0011001100110011ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_18) = {0x0012001200120012ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_20) = {0x0014001400140014ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_22) = {0x0016001600160016ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_28) = {0x001C001C001C001CULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_32) = {0x0020002000200020ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_53) = {0x0035003500350035ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_64) = {0x0040004000400040ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = {0x0080008000800080ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_512) = {0x0200020002000200ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_m8tom5) = {0xFFFBFFFAFFF9FFF8ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_m4tom1) = {0xFFFFFFFEFFFDFFFCULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_1to4) = {0x0004000300020001ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_5to8) = {0x0008000700060005ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_0to3) = {0x0003000200010000ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_4to7) = {0x0007000600050004ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_8tob) = {0x000b000a00090008ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pw_ctof) = {0x000f000e000d000cULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pb_1) = {0x0101010101010101ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pb_3) = {0x0303030303030303ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pb_80) = {0x8080808080808080ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pb_A1) = {0xA1A1A1A1A1A1A1A1ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_pb_FE) = {0xFEFEFEFEFEFEFEFEULL};
DECLARE_ALIGNED(8, const uint64_t, ff_rnd) = {0x0004000400040004ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_rnd2) = {0x0040004000400040ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_rnd3) = {0x0020002000200020ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_wm1010) = {0xFFFF0000FFFF0000ULL};
DECLARE_ALIGNED(8, const uint64_t, ff_d40000) = {0x0000000000040000ULL};

71
externals/ffmpeg/libavcodec/mips/constants.h vendored Executable file
View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_CONSTANTS_H
#define AVCODEC_MIPS_CONSTANTS_H
#include <stdint.h>
extern const uint64_t ff_pw_1;
extern const uint64_t ff_pw_2;
extern const uint64_t ff_pw_3;
extern const uint64_t ff_pw_4;
extern const uint64_t ff_pw_5;
extern const uint64_t ff_pw_6;
extern const uint64_t ff_pw_8;
extern const uint64_t ff_pw_9;
extern const uint64_t ff_pw_10;
extern const uint64_t ff_pw_12;
extern const uint64_t ff_pw_15;
extern const uint64_t ff_pw_16;
extern const uint64_t ff_pw_17;
extern const uint64_t ff_pw_18;
extern const uint64_t ff_pw_20;
extern const uint64_t ff_pw_22;
extern const uint64_t ff_pw_28;
extern const uint64_t ff_pw_32;
extern const uint64_t ff_pw_53;
extern const uint64_t ff_pw_64;
extern const uint64_t ff_pw_128;
extern const uint64_t ff_pw_512;
extern const uint64_t ff_pw_m8tom5;
extern const uint64_t ff_pw_m4tom1;
extern const uint64_t ff_pw_1to4;
extern const uint64_t ff_pw_5to8;
extern const uint64_t ff_pw_0to3;
extern const uint64_t ff_pw_4to7;
extern const uint64_t ff_pw_8tob;
extern const uint64_t ff_pw_ctof;
extern const uint64_t ff_pb_1;
extern const uint64_t ff_pb_3;
extern const uint64_t ff_pb_80;
extern const uint64_t ff_pb_A1;
extern const uint64_t ff_pb_FE;
extern const uint64_t ff_rnd;
extern const uint64_t ff_rnd2;
extern const uint64_t ff_rnd3;
extern const uint64_t ff_wm1010;
extern const uint64_t ff_d40000;
#endif /* AVCODEC_MIPS_CONSTANTS_H */

517
externals/ffmpeg/libavcodec/mips/fft_mips.c vendored Executable file
View File

@@ -0,0 +1,517 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Stanislav Ocovaj (socovaj@mips.com)
* Author: Zoran Lukic (zoranl@mips.com)
*
* Optimized MDCT/IMDCT and FFT transforms
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavcodec/fft.h"
#include "libavcodec/fft_table.h"
#include "libavutil/mips/asmdefs.h"
/**
* FFT transform
*/
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z)
{
int nbits, i, n, num_transforms, offset, step;
int n4, n2, n34;
FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
FFTComplex *tmpz;
float w_re, w_im;
float *w_re_ptr, *w_im_ptr;
const int fft_size = (1 << s->nbits);
float pom, pom1, pom2, pom3;
float temp, temp1, temp3, temp4;
FFTComplex * tmpz_n2, * tmpz_n34, * tmpz_n4;
FFTComplex * tmpz_n2_i, * tmpz_n34_i, * tmpz_n4_i, * tmpz_i;
num_transforms = (21845 >> (17 - s->nbits)) | 1;
for (n=0; n<num_transforms; n++) {
offset = ff_fft_offsets_lut[n] << 2;
tmpz = z + offset;
tmp1 = tmpz[0].re + tmpz[1].re;
tmp5 = tmpz[2].re + tmpz[3].re;
tmp2 = tmpz[0].im + tmpz[1].im;
tmp6 = tmpz[2].im + tmpz[3].im;
tmp3 = tmpz[0].re - tmpz[1].re;
tmp8 = tmpz[2].im - tmpz[3].im;
tmp4 = tmpz[0].im - tmpz[1].im;
tmp7 = tmpz[2].re - tmpz[3].re;
tmpz[0].re = tmp1 + tmp5;
tmpz[2].re = tmp1 - tmp5;
tmpz[0].im = tmp2 + tmp6;
tmpz[2].im = tmp2 - tmp6;
tmpz[1].re = tmp3 + tmp8;
tmpz[3].re = tmp3 - tmp8;
tmpz[1].im = tmp4 - tmp7;
tmpz[3].im = tmp4 + tmp7;
}
if (fft_size < 8)
return;
num_transforms = (num_transforms >> 1) | 1;
for (n=0; n<num_transforms; n++) {
offset = ff_fft_offsets_lut[n] << 3;
tmpz = z + offset;
__asm__ volatile (
"lwc1 %[tmp1], 32(%[tmpz]) \n\t"
"lwc1 %[pom], 40(%[tmpz]) \n\t"
"lwc1 %[tmp3], 48(%[tmpz]) \n\t"
"lwc1 %[pom1], 56(%[tmpz]) \n\t"
"lwc1 %[tmp2], 36(%[tmpz]) \n\t"
"lwc1 %[pom2], 44(%[tmpz]) \n\t"
"lwc1 %[pom3], 60(%[tmpz]) \n\t"
"lwc1 %[tmp4], 52(%[tmpz]) \n\t"
"add.s %[tmp1], %[tmp1], %[pom] \n\t" // tmp1 = tmpz[4].re + tmpz[5].re;
"add.s %[tmp3], %[tmp3], %[pom1] \n\t" // tmp3 = tmpz[6].re + tmpz[7].re;
"add.s %[tmp2], %[tmp2], %[pom2] \n\t" // tmp2 = tmpz[4].im + tmpz[5].im;
"lwc1 %[pom], 40(%[tmpz]) \n\t"
"add.s %[tmp4], %[tmp4], %[pom3] \n\t" // tmp4 = tmpz[6].im + tmpz[7].im;
"add.s %[tmp5], %[tmp1], %[tmp3] \n\t" // tmp5 = tmp1 + tmp3;
"sub.s %[tmp7], %[tmp1], %[tmp3] \n\t" // tmp7 = tmp1 - tmp3;
"lwc1 %[tmp1], 32(%[tmpz]) \n\t"
"lwc1 %[pom1], 44(%[tmpz]) \n\t"
"add.s %[tmp6], %[tmp2], %[tmp4] \n\t" // tmp6 = tmp2 + tmp4;
"sub.s %[tmp8], %[tmp2], %[tmp4] \n\t" // tmp8 = tmp2 - tmp4;
"lwc1 %[tmp2], 36(%[tmpz]) \n\t"
"lwc1 %[pom2], 56(%[tmpz]) \n\t"
"lwc1 %[pom3], 60(%[tmpz]) \n\t"
"lwc1 %[tmp3], 48(%[tmpz]) \n\t"
"lwc1 %[tmp4], 52(%[tmpz]) \n\t"
"sub.s %[tmp1], %[tmp1], %[pom] \n\t" // tmp1 = tmpz[4].re - tmpz[5].re;
"lwc1 %[pom], 0(%[tmpz]) \n\t"
"sub.s %[tmp2], %[tmp2], %[pom1] \n\t" // tmp2 = tmpz[4].im - tmpz[5].im;
"sub.s %[tmp3], %[tmp3], %[pom2] \n\t" // tmp3 = tmpz[6].re - tmpz[7].re;
"lwc1 %[pom2], 4(%[tmpz]) \n\t"
"sub.s %[pom1], %[pom], %[tmp5] \n\t"
"sub.s %[tmp4], %[tmp4], %[pom3] \n\t" // tmp4 = tmpz[6].im - tmpz[7].im;
"add.s %[pom3], %[pom], %[tmp5] \n\t"
"sub.s %[pom], %[pom2], %[tmp6] \n\t"
"add.s %[pom2], %[pom2], %[tmp6] \n\t"
"swc1 %[pom1], 32(%[tmpz]) \n\t" // tmpz[4].re = tmpz[0].re - tmp5;
"swc1 %[pom3], 0(%[tmpz]) \n\t" // tmpz[0].re = tmpz[0].re + tmp5;
"swc1 %[pom], 36(%[tmpz]) \n\t" // tmpz[4].im = tmpz[0].im - tmp6;
"swc1 %[pom2], 4(%[tmpz]) \n\t" // tmpz[0].im = tmpz[0].im + tmp6;
"lwc1 %[pom1], 16(%[tmpz]) \n\t"
"lwc1 %[pom3], 20(%[tmpz]) \n\t"
"li.s %[pom], 0.7071067812 \n\t" // float pom = 0.7071067812f;
"add.s %[temp1],%[tmp1], %[tmp2] \n\t"
"sub.s %[temp], %[pom1], %[tmp8] \n\t"
"add.s %[pom2], %[pom3], %[tmp7] \n\t"
"sub.s %[temp3],%[tmp3], %[tmp4] \n\t"
"sub.s %[temp4],%[tmp2], %[tmp1] \n\t"
"swc1 %[temp], 48(%[tmpz]) \n\t" // tmpz[6].re = tmpz[2].re - tmp8;
"swc1 %[pom2], 52(%[tmpz]) \n\t" // tmpz[6].im = tmpz[2].im + tmp7;
"add.s %[pom1], %[pom1], %[tmp8] \n\t"
"sub.s %[pom3], %[pom3], %[tmp7] \n\t"
"add.s %[tmp3], %[tmp3], %[tmp4] \n\t"
"mul.s %[tmp5], %[pom], %[temp1] \n\t" // tmp5 = pom * (tmp1 + tmp2);
"mul.s %[tmp7], %[pom], %[temp3] \n\t" // tmp7 = pom * (tmp3 - tmp4);
"mul.s %[tmp6], %[pom], %[temp4] \n\t" // tmp6 = pom * (tmp2 - tmp1);
"mul.s %[tmp8], %[pom], %[tmp3] \n\t" // tmp8 = pom * (tmp3 + tmp4);
"swc1 %[pom1], 16(%[tmpz]) \n\t" // tmpz[2].re = tmpz[2].re + tmp8;
"swc1 %[pom3], 20(%[tmpz]) \n\t" // tmpz[2].im = tmpz[2].im - tmp7;
"add.s %[tmp1], %[tmp5], %[tmp7] \n\t" // tmp1 = tmp5 + tmp7;
"sub.s %[tmp3], %[tmp5], %[tmp7] \n\t" // tmp3 = tmp5 - tmp7;
"add.s %[tmp2], %[tmp6], %[tmp8] \n\t" // tmp2 = tmp6 + tmp8;
"sub.s %[tmp4], %[tmp6], %[tmp8] \n\t" // tmp4 = tmp6 - tmp8;
"lwc1 %[temp], 8(%[tmpz]) \n\t"
"lwc1 %[temp1],12(%[tmpz]) \n\t"
"lwc1 %[pom], 24(%[tmpz]) \n\t"
"lwc1 %[pom2], 28(%[tmpz]) \n\t"
"sub.s %[temp4],%[temp], %[tmp1] \n\t"
"sub.s %[temp3],%[temp1], %[tmp2] \n\t"
"add.s %[temp], %[temp], %[tmp1] \n\t"
"add.s %[temp1],%[temp1], %[tmp2] \n\t"
"sub.s %[pom1], %[pom], %[tmp4] \n\t"
"add.s %[pom3], %[pom2], %[tmp3] \n\t"
"add.s %[pom], %[pom], %[tmp4] \n\t"
"sub.s %[pom2], %[pom2], %[tmp3] \n\t"
"swc1 %[temp4],40(%[tmpz]) \n\t" // tmpz[5].re = tmpz[1].re - tmp1;
"swc1 %[temp3],44(%[tmpz]) \n\t" // tmpz[5].im = tmpz[1].im - tmp2;
"swc1 %[temp], 8(%[tmpz]) \n\t" // tmpz[1].re = tmpz[1].re + tmp1;
"swc1 %[temp1],12(%[tmpz]) \n\t" // tmpz[1].im = tmpz[1].im + tmp2;
"swc1 %[pom1], 56(%[tmpz]) \n\t" // tmpz[7].re = tmpz[3].re - tmp4;
"swc1 %[pom3], 60(%[tmpz]) \n\t" // tmpz[7].im = tmpz[3].im + tmp3;
"swc1 %[pom], 24(%[tmpz]) \n\t" // tmpz[3].re = tmpz[3].re + tmp4;
"swc1 %[pom2], 28(%[tmpz]) \n\t" // tmpz[3].im = tmpz[3].im - tmp3;
: [tmp1]"=&f"(tmp1), [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2),
[tmp3]"=&f"(tmp3), [tmp2]"=&f"(tmp2), [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp7]"=&f"(tmp7),
[tmp6]"=&f"(tmp6), [tmp8]"=&f"(tmp8), [pom3]"=&f"(pom3),[temp]"=&f"(temp), [temp1]"=&f"(temp1),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4)
: [tmpz]"r"(tmpz)
: "memory"
);
}
step = 1 << (MAX_LOG2_NFFT - 4);
n4 = 4;
for (nbits=4; nbits<=s->nbits; nbits++) {
num_transforms = (num_transforms >> 1) | 1;
n2 = 2 * n4;
n34 = 3 * n4;
for (n=0; n<num_transforms; n++) {
offset = ff_fft_offsets_lut[n] << nbits;
tmpz = z + offset;
tmpz_n2 = tmpz + n2;
tmpz_n4 = tmpz + n4;
tmpz_n34 = tmpz + n34;
__asm__ volatile (
"lwc1 %[pom1], 0(%[tmpz_n2]) \n\t"
"lwc1 %[pom], 0(%[tmpz_n34]) \n\t"
"lwc1 %[pom2], 4(%[tmpz_n2]) \n\t"
"lwc1 %[pom3], 4(%[tmpz_n34]) \n\t"
"lwc1 %[temp1],0(%[tmpz]) \n\t"
"lwc1 %[temp3],4(%[tmpz]) \n\t"
"add.s %[tmp5], %[pom1], %[pom] \n\t" // tmp5 = tmpz[ n2].re + tmpz[n34].re;
"sub.s %[tmp1], %[pom1], %[pom] \n\t" // tmp1 = tmpz[ n2].re - tmpz[n34].re;
"add.s %[tmp6], %[pom2], %[pom3] \n\t" // tmp6 = tmpz[ n2].im + tmpz[n34].im;
"sub.s %[tmp2], %[pom2], %[pom3] \n\t" // tmp2 = tmpz[ n2].im - tmpz[n34].im;
"sub.s %[temp], %[temp1], %[tmp5] \n\t"
"add.s %[temp1],%[temp1], %[tmp5] \n\t"
"sub.s %[temp4],%[temp3], %[tmp6] \n\t"
"add.s %[temp3],%[temp3], %[tmp6] \n\t"
"swc1 %[temp], 0(%[tmpz_n2]) \n\t" // tmpz[ n2].re = tmpz[ 0].re - tmp5;
"swc1 %[temp1],0(%[tmpz]) \n\t" // tmpz[ 0].re = tmpz[ 0].re + tmp5;
"lwc1 %[pom1], 0(%[tmpz_n4]) \n\t"
"swc1 %[temp4],4(%[tmpz_n2]) \n\t" // tmpz[ n2].im = tmpz[ 0].im - tmp6;
"lwc1 %[temp], 4(%[tmpz_n4]) \n\t"
"swc1 %[temp3],4(%[tmpz]) \n\t" // tmpz[ 0].im = tmpz[ 0].im + tmp6;
"sub.s %[pom], %[pom1], %[tmp2] \n\t"
"add.s %[pom1], %[pom1], %[tmp2] \n\t"
"add.s %[temp1],%[temp], %[tmp1] \n\t"
"sub.s %[temp], %[temp], %[tmp1] \n\t"
"swc1 %[pom], 0(%[tmpz_n34]) \n\t" // tmpz[n34].re = tmpz[n4].re - tmp2;
"swc1 %[pom1], 0(%[tmpz_n4]) \n\t" // tmpz[ n4].re = tmpz[n4].re + tmp2;
"swc1 %[temp1],4(%[tmpz_n34]) \n\t" // tmpz[n34].im = tmpz[n4].im + tmp1;
"swc1 %[temp], 4(%[tmpz_n4]) \n\t" // tmpz[ n4].im = tmpz[n4].im - tmp1;
: [tmp5]"=&f"(tmp5),
[tmp1]"=&f"(tmp1), [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2),
[tmp2]"=&f"(tmp2), [tmp6]"=&f"(tmp6), [pom3]"=&f"(pom3),
[temp]"=&f"(temp), [temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4)
: [tmpz]"r"(tmpz), [tmpz_n2]"r"(tmpz_n2), [tmpz_n34]"r"(tmpz_n34), [tmpz_n4]"r"(tmpz_n4)
: "memory"
);
w_re_ptr = (float*)(ff_cos_131072 + step);
w_im_ptr = (float*)(ff_cos_131072 + MAX_FFT_SIZE/4 - step);
for (i=1; i<n4; i++) {
w_re = w_re_ptr[0];
w_im = w_im_ptr[0];
tmpz_n2_i = tmpz_n2 + i;
tmpz_n4_i = tmpz_n4 + i;
tmpz_n34_i= tmpz_n34 + i;
tmpz_i = tmpz + i;
__asm__ volatile (
"lwc1 %[temp], 0(%[tmpz_n2_i]) \n\t"
"lwc1 %[temp1], 4(%[tmpz_n2_i]) \n\t"
"lwc1 %[pom], 0(%[tmpz_n34_i]) \n\t"
"lwc1 %[pom1], 4(%[tmpz_n34_i]) \n\t"
"mul.s %[temp3], %[w_im], %[temp] \n\t"
"mul.s %[temp4], %[w_im], %[temp1] \n\t"
"mul.s %[pom2], %[w_im], %[pom1] \n\t"
"mul.s %[pom3], %[w_im], %[pom] \n\t"
"msub.s %[tmp2], %[temp3], %[w_re], %[temp1] \n\t" // tmp2 = w_re * tmpz[ n2+i].im - w_im * tmpz[ n2+i].re;
"madd.s %[tmp1], %[temp4], %[w_re], %[temp] \n\t" // tmp1 = w_re * tmpz[ n2+i].re + w_im * tmpz[ n2+i].im;
"msub.s %[tmp3], %[pom2], %[w_re], %[pom] \n\t" // tmp3 = w_re * tmpz[n34+i].re - w_im * tmpz[n34+i].im;
"madd.s %[tmp4], %[pom3], %[w_re], %[pom1] \n\t" // tmp4 = w_re * tmpz[n34+i].im + w_im * tmpz[n34+i].re;
"lwc1 %[temp], 0(%[tmpz_i]) \n\t"
"lwc1 %[pom], 4(%[tmpz_i]) \n\t"
"add.s %[tmp5], %[tmp1], %[tmp3] \n\t" // tmp5 = tmp1 + tmp3;
"sub.s %[tmp1], %[tmp1], %[tmp3] \n\t" // tmp1 = tmp1 - tmp3;
"add.s %[tmp6], %[tmp2], %[tmp4] \n\t" // tmp6 = tmp2 + tmp4;
"sub.s %[tmp2], %[tmp2], %[tmp4] \n\t" // tmp2 = tmp2 - tmp4;
"sub.s %[temp1], %[temp], %[tmp5] \n\t"
"add.s %[temp], %[temp], %[tmp5] \n\t"
"sub.s %[pom1], %[pom], %[tmp6] \n\t"
"add.s %[pom], %[pom], %[tmp6] \n\t"
"lwc1 %[temp3], 0(%[tmpz_n4_i]) \n\t"
"lwc1 %[pom2], 4(%[tmpz_n4_i]) \n\t"
"swc1 %[temp1], 0(%[tmpz_n2_i]) \n\t" // tmpz[ n2+i].re = tmpz[ i].re - tmp5;
"swc1 %[temp], 0(%[tmpz_i]) \n\t" // tmpz[ i].re = tmpz[ i].re + tmp5;
"swc1 %[pom1], 4(%[tmpz_n2_i]) \n\t" // tmpz[ n2+i].im = tmpz[ i].im - tmp6;
"swc1 %[pom] , 4(%[tmpz_i]) \n\t" // tmpz[ i].im = tmpz[ i].im + tmp6;
"sub.s %[temp4], %[temp3], %[tmp2] \n\t"
"add.s %[pom3], %[pom2], %[tmp1] \n\t"
"add.s %[temp3], %[temp3], %[tmp2] \n\t"
"sub.s %[pom2], %[pom2], %[tmp1] \n\t"
"swc1 %[temp4], 0(%[tmpz_n34_i]) \n\t" // tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
"swc1 %[pom3], 4(%[tmpz_n34_i]) \n\t" // tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
"swc1 %[temp3], 0(%[tmpz_n4_i]) \n\t" // tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
"swc1 %[pom2], 4(%[tmpz_n4_i]) \n\t" // tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
: [tmp1]"=&f"(tmp1), [tmp2]"=&f" (tmp2), [temp]"=&f"(temp), [tmp3]"=&f"(tmp3),
[tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp6]"=&f"(tmp6),
[temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
[pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2), [pom3]"=&f"(pom3)
: [w_re]"f"(w_re), [w_im]"f"(w_im),
[tmpz_i]"r"(tmpz_i),[tmpz_n2_i]"r"(tmpz_n2_i),
[tmpz_n34_i]"r"(tmpz_n34_i), [tmpz_n4_i]"r"(tmpz_n4_i)
: "memory"
);
w_re_ptr += step;
w_im_ptr -= step;
}
}
step >>= 1;
n4 <<= 1;
}
}
/**
* MDCT/IMDCT transforms.
*/
static void ff_imdct_half_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
{
int k, n8, n4, n2, n, j;
const uint16_t *revtab = s->revtab;
const FFTSample *tcos = s->tcos;
const FFTSample *tsin = s->tsin;
const FFTSample *in1, *in2, *in3, *in4;
FFTComplex *z = (FFTComplex *)output;
int j1;
const float *tcos1, *tsin1, *tcos2, *tsin2;
float temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
FFTComplex *z1, *z2;
n = 1 << s->mdct_bits;
n2 = n >> 1;
n4 = n >> 2;
n8 = n >> 3;
/* pre rotation */
in1 = input;
in2 = input + n2 - 1;
in3 = input + 2;
in4 = input + n2 - 3;
tcos1 = tcos;
tsin1 = tsin;
/* n4 = 64 or 128 */
for(k = 0; k < n4; k += 2) {
j = revtab[k ];
j1 = revtab[k + 1];
__asm__ volatile (
"lwc1 %[temp1], 0(%[in2]) \t\n"
"lwc1 %[temp2], 0(%[tcos1]) \t\n"
"lwc1 %[temp3], 0(%[tsin1]) \t\n"
"lwc1 %[temp4], 0(%[in1]) \t\n"
"lwc1 %[temp5], 0(%[in4]) \t\n"
"mul.s %[temp9], %[temp1], %[temp2] \t\n"
"mul.s %[temp10], %[temp1], %[temp3] \t\n"
"lwc1 %[temp6], 4(%[tcos1]) \t\n"
"lwc1 %[temp7], 4(%[tsin1]) \t\n"
"nmsub.s %[temp9], %[temp9], %[temp4], %[temp3] \t\n"
"madd.s %[temp10], %[temp10], %[temp4], %[temp2] \t\n"
"mul.s %[temp11], %[temp5], %[temp6] \t\n"
"mul.s %[temp12], %[temp5], %[temp7] \t\n"
"lwc1 %[temp8], 0(%[in3]) \t\n"
PTR_ADDIU " %[tcos1], %[tcos1], 8 \t\n"
PTR_ADDIU " %[tsin1], %[tsin1], 8 \t\n"
PTR_ADDIU " %[in1], %[in1], 16 \t\n"
"nmsub.s %[temp11], %[temp11], %[temp8], %[temp7] \t\n"
"madd.s %[temp12], %[temp12], %[temp8], %[temp6] \t\n"
PTR_ADDIU " %[in2], %[in2], -16 \t\n"
PTR_ADDIU " %[in3], %[in3], 16 \t\n"
PTR_ADDIU " %[in4], %[in4], -16 \t\n"
: [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
[temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
[temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [temp10]"=&f"(temp10),
[temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
[tsin1]"+r"(tsin1), [tcos1]"+r"(tcos1),
[in1]"+r"(in1), [in2]"+r"(in2),
[in3]"+r"(in3), [in4]"+r"(in4)
:
: "memory"
);
z[j ].re = temp9;
z[j ].im = temp10;
z[j1].re = temp11;
z[j1].im = temp12;
}
s->fft_calc(s, z);
/* post rotation + reordering */
/* n8 = 32 or 64 */
for(k = 0; k < n8; k += 2) {
tcos1 = &tcos[n8 - k - 2];
tsin1 = &tsin[n8 - k - 2];
tcos2 = &tcos[n8 + k];
tsin2 = &tsin[n8 + k];
z1 = &z[n8 - k - 2];
z2 = &z[n8 + k ];
__asm__ volatile (
"lwc1 %[temp1], 12(%[z1]) \t\n"
"lwc1 %[temp2], 4(%[tsin1]) \t\n"
"lwc1 %[temp3], 4(%[tcos1]) \t\n"
"lwc1 %[temp4], 8(%[z1]) \t\n"
"lwc1 %[temp5], 4(%[z1]) \t\n"
"mul.s %[temp9], %[temp1], %[temp2] \t\n"
"mul.s %[temp10], %[temp1], %[temp3] \t\n"
"lwc1 %[temp6], 0(%[tsin1]) \t\n"
"lwc1 %[temp7], 0(%[tcos1]) \t\n"
"nmsub.s %[temp9], %[temp9], %[temp4], %[temp3] \t\n"
"madd.s %[temp10], %[temp10], %[temp4], %[temp2] \t\n"
"mul.s %[temp11], %[temp5], %[temp6] \t\n"
"mul.s %[temp12], %[temp5], %[temp7] \t\n"
"lwc1 %[temp8], 0(%[z1]) \t\n"
"lwc1 %[temp1], 4(%[z2]) \t\n"
"lwc1 %[temp2], 0(%[tsin2]) \t\n"
"lwc1 %[temp3], 0(%[tcos2]) \t\n"
"nmsub.s %[temp11], %[temp11], %[temp8], %[temp7] \t\n"
"madd.s %[temp12], %[temp12], %[temp8], %[temp6] \t\n"
"mul.s %[temp13], %[temp1], %[temp2] \t\n"
"mul.s %[temp14], %[temp1], %[temp3] \t\n"
"lwc1 %[temp4], 0(%[z2]) \t\n"
"lwc1 %[temp5], 12(%[z2]) \t\n"
"lwc1 %[temp6], 4(%[tsin2]) \t\n"
"lwc1 %[temp7], 4(%[tcos2]) \t\n"
"nmsub.s %[temp13], %[temp13], %[temp4], %[temp3] \t\n"
"madd.s %[temp14], %[temp14], %[temp4], %[temp2] \t\n"
"mul.s %[temp15], %[temp5], %[temp6] \t\n"
"mul.s %[temp16], %[temp5], %[temp7] \t\n"
"lwc1 %[temp8], 8(%[z2]) \t\n"
"nmsub.s %[temp15], %[temp15], %[temp8], %[temp7] \t\n"
"madd.s %[temp16], %[temp16], %[temp8], %[temp6] \t\n"
: [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
[temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
[temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [temp10]"=&f"(temp10),
[temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
[temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
[temp15]"=&f"(temp15), [temp16]"=&f"(temp16)
: [z1]"r"(z1), [z2]"r"(z2),
[tsin1]"r"(tsin1), [tcos1]"r"(tcos1),
[tsin2]"r"(tsin2), [tcos2]"r"(tcos2)
: "memory"
);
z1[1].re = temp9;
z1[1].im = temp14;
z2[0].re = temp13;
z2[0].im = temp10;
z1[0].re = temp11;
z1[0].im = temp16;
z2[1].re = temp15;
z2[1].im = temp12;
}
}
/**
* Compute inverse MDCT of size N = 2^nbits
* @param output N samples
* @param input N/2 samples
*/
static void ff_imdct_calc_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
{
int k;
int n = 1 << s->mdct_bits;
int n2 = n >> 1;
int n4 = n >> 2;
ff_imdct_half_mips(s, output+n4, input);
for(k = 0; k < n4; k+=4) {
output[k] = -output[n2-k-1];
output[k+1] = -output[n2-k-2];
output[k+2] = -output[n2-k-3];
output[k+3] = -output[n2-k-4];
output[n-k-1] = output[n2+k];
output[n-k-2] = output[n2+k+1];
output[n-k-3] = output[n2+k+2];
output[n-k-4] = output[n2+k+3];
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
av_cold void ff_fft_init_mips(FFTContext *s)
{
int n=0;
ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n);
ff_init_ff_cos_tabs(17);
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
s->fft_calc = ff_fft_calc_mips;
#if CONFIG_MDCT
s->imdct_calc = ff_imdct_calc_mips;
s->imdct_half = ff_imdct_half_mips;
#endif
#endif
#endif
}

View File

@@ -0,0 +1,141 @@
/*
* Format Conversion Utils for MIPS
*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of is
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Zoran Lukic (zoranl@mips.com)
* Author: Nedeljko Babic (nbabic@mips.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/fmtconvert.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
static void int32_to_float_fmul_scalar_mips(float *dst, const int *src,
float mul, int len)
{
/*
* variables used in inline assembler
*/
float temp1, temp3, temp5, temp7, temp9, temp11, temp13, temp15;
int rpom1, rpom2, rpom11, rpom21, rpom12, rpom22, rpom13, rpom23;
const int *src_end = src + len;
/*
* loop is 8 times unrolled in assembler in order to achieve better performance
*/
__asm__ volatile (
"i32tf_lp%=: \n\t"
"lw %[rpom11], 0(%[src]) \n\t"
"lw %[rpom21], 4(%[src]) \n\t"
"lw %[rpom1], 8(%[src]) \n\t"
"lw %[rpom2], 12(%[src]) \n\t"
"mtc1 %[rpom11], %[temp1] \n\t"
"mtc1 %[rpom21], %[temp3] \n\t"
"mtc1 %[rpom1], %[temp5] \n\t"
"mtc1 %[rpom2], %[temp7] \n\t"
"lw %[rpom13], 16(%[src]) \n\t"
"lw %[rpom23], 20(%[src]) \n\t"
"lw %[rpom12], 24(%[src]) \n\t"
"lw %[rpom22], 28(%[src]) \n\t"
"mtc1 %[rpom13], %[temp9] \n\t"
"mtc1 %[rpom23], %[temp11] \n\t"
"mtc1 %[rpom12], %[temp13] \n\t"
"mtc1 %[rpom22], %[temp15] \n\t"
PTR_ADDIU "%[src], 32 \n\t"
"cvt.s.w %[temp1], %[temp1] \n\t"
"cvt.s.w %[temp3], %[temp3] \n\t"
"cvt.s.w %[temp5], %[temp5] \n\t"
"cvt.s.w %[temp7], %[temp7] \n\t"
"cvt.s.w %[temp9], %[temp9] \n\t"
"cvt.s.w %[temp11], %[temp11] \n\t"
"cvt.s.w %[temp13], %[temp13] \n\t"
"cvt.s.w %[temp15], %[temp15] \n\t"
"mul.s %[temp1], %[temp1], %[mul] \n\t"
"mul.s %[temp3], %[temp3], %[mul] \n\t"
"mul.s %[temp5], %[temp5], %[mul] \n\t"
"mul.s %[temp7], %[temp7], %[mul] \n\t"
"mul.s %[temp9], %[temp9], %[mul] \n\t"
"mul.s %[temp11], %[temp11], %[mul] \n\t"
"mul.s %[temp13], %[temp13], %[mul] \n\t"
"mul.s %[temp15], %[temp15], %[mul] \n\t"
"swc1 %[temp1], 0(%[dst]) \n\t" /*dst[i] = src[i] * mul; */
"swc1 %[temp3], 4(%[dst]) \n\t" /*dst[i+1] = src[i+1] * mul;*/
"swc1 %[temp5], 8(%[dst]) \n\t" /*dst[i+2] = src[i+2] * mul;*/
"swc1 %[temp7], 12(%[dst]) \n\t" /*dst[i+3] = src[i+3] * mul;*/
"swc1 %[temp9], 16(%[dst]) \n\t" /*dst[i+4] = src[i+4] * mul;*/
"swc1 %[temp11], 20(%[dst]) \n\t" /*dst[i+5] = src[i+5] * mul;*/
"swc1 %[temp13], 24(%[dst]) \n\t" /*dst[i+6] = src[i+6] * mul;*/
"swc1 %[temp15], 28(%[dst]) \n\t" /*dst[i+7] = src[i+7] * mul;*/
PTR_ADDIU "%[dst], 32 \n\t"
"bne %[src], %[src_end], i32tf_lp%= \n\t"
: [temp1]"=&f"(temp1), [temp11]"=&f"(temp11),
[temp13]"=&f"(temp13), [temp15]"=&f"(temp15),
[temp3]"=&f"(temp3), [temp5]"=&f"(temp5),
[temp7]"=&f"(temp7), [temp9]"=&f"(temp9),
[rpom1]"=&r"(rpom1), [rpom2]"=&r"(rpom2),
[rpom11]"=&r"(rpom11), [rpom21]"=&r"(rpom21),
[rpom12]"=&r"(rpom12), [rpom22]"=&r"(rpom22),
[rpom13]"=&r"(rpom13), [rpom23]"=&r"(rpom23),
[dst]"+r"(dst), [src]"+r"(src)
: [mul]"f"(mul), [src_end]"r"(src_end)
: "memory"
);
}
#endif /* HAVE_INLINE_ASM */
av_cold void ff_fmt_convert_init_mips(FmtConvertContext *c)
{
#if HAVE_INLINE_ASM
c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_mips;
#endif
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h263dsp_mips.h"
#if HAVE_MSA
static av_cold void h263dsp_init_msa(H263DSPContext *c)
{
c->h263_h_loop_filter = ff_h263_h_loop_filter_msa;
c->h263_v_loop_filter = ff_h263_v_loop_filter_msa;
}
#endif // #if HAVE_MSA
av_cold void ff_h263dsp_init_mips(H263DSPContext *c)
{
#if HAVE_MSA
h263dsp_init_msa(c);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_H263DSP_MIPS_H
#define AVCODEC_MIPS_H263DSP_MIPS_H
#include "libavcodec/mpegvideo.h"
void ff_h263_h_loop_filter_msa(uint8_t *src, int stride, int q_scale);
void ff_h263_v_loop_filter_msa(uint8_t *src, int stride, int q_scale);
void ff_dct_unquantize_mpeg2_inter_msa(MpegEncContext *s, int16_t *block,
int32_t index, int32_t q_scale);
void ff_dct_unquantize_h263_inter_msa(MpegEncContext *s, int16_t *block,
int32_t index, int32_t q_scale);
void ff_dct_unquantize_h263_intra_msa(MpegEncContext *s, int16_t *block,
int32_t index, int32_t q_scale);
int ff_pix_sum_msa(uint8_t *pix, int line_size);
#endif // #ifndef AVCODEC_MIPS_H263DSP_MIPS_H

161
externals/ffmpeg/libavcodec/mips/h263dsp_msa.c vendored Executable file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "h263dsp_mips.h"
static const uint8_t h263_loop_filter_strength_msa[32] = {
0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7,
7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
};
static void h263_h_loop_filter_msa(uint8_t *src, int32_t stride, int32_t qscale)
{
int32_t strength = h263_loop_filter_strength_msa[qscale];
v16u8 in0, in1, in2, in3, in4, in5, in6, in7;
v8i16 temp0, temp1, temp2;
v8i16 diff0, diff2, diff4, diff6, diff8;
v8i16 d0, a_d0, str_x2, str;
src -= 2;
LD_UB8(src, stride, in0, in1, in2, in3, in4, in5, in6, in7);
TRANSPOSE8x4_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in3, in2, in1);
temp0 = (v8i16) __msa_ilvr_b((v16i8) in0, (v16i8) in1);
a_d0 = __msa_hsub_u_h((v16u8) temp0, (v16u8) temp0);
temp2 = (v8i16) __msa_ilvr_b((v16i8) in2, (v16i8) in3);
temp2 = __msa_hsub_u_h((v16u8) temp2, (v16u8) temp2);
temp2 <<= 2;
diff0 = a_d0 + temp2;
diff2 = -(-diff0 >> 3);
str_x2 = __msa_fill_h(-(strength << 1));
temp0 = (str_x2 <= diff2);
diff2 = (v8i16) __msa_bmz_v((v16u8) diff2, (v16u8) temp0, (v16u8) temp0);
temp2 = str_x2 - diff2;
str = __msa_fill_h(-strength);
temp0 = (diff2 < str);
diff2 = (v8i16) __msa_bmnz_v((v16u8) diff2, (v16u8) temp2, (v16u8) temp0);
diff4 = diff0 >> 3;
str_x2 = __msa_fill_h(strength << 1);
temp0 = (diff4 <= str_x2);
diff4 = (v8i16) __msa_bmz_v((v16u8) diff4, (v16u8) temp0, (v16u8) temp0);
temp2 = str_x2 - diff4;
str = __msa_fill_h(strength);
temp0 = (str < diff4);
diff4 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) temp2, (v16u8) temp0);
temp0 = __msa_clti_s_h(diff0, 0);
d0 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) diff2, (v16u8) temp0);
diff2 = -diff2 >> 1;
diff4 >>= 1;
diff8 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) diff2, (v16u8) temp0);
diff6 = (-a_d0) >> 2;
diff6 = -(diff6);
temp2 = -diff8;
temp0 = (diff6 < temp2);
diff6 = (v8i16) __msa_bmnz_v((v16u8) diff6, (v16u8) temp2, (v16u8) temp0);
diff2 = a_d0 >> 2;
temp0 = (diff2 <= diff8);
diff2 = (v8i16) __msa_bmz_v((v16u8) diff2, (v16u8) diff8, (v16u8) temp0);
temp0 = __msa_clti_s_h(a_d0, 0);
diff6 = (v8i16) __msa_bmz_v((v16u8) diff6, (v16u8) diff2, (v16u8) temp0);
PCKEV_B2_SH(a_d0, diff6, a_d0, d0, diff6, d0);
in0 = (v16u8) ((v16i8) in0 - (v16i8) diff6);
in1 = (v16u8) ((v16i8) in1 + (v16i8) diff6);
in3 = __msa_xori_b(in3, 128);
in3 = (v16u8) __msa_adds_s_b((v16i8) in3, (v16i8) d0);
in3 = __msa_xori_b(in3, 128);
in2 = __msa_subsus_u_b(in2, (v16i8) d0);
ILVR_B2_SH(in3, in0, in1, in2, temp0, temp1);
in0 = (v16u8) __msa_ilvr_h(temp1, temp0);
in3 = (v16u8) __msa_ilvl_h(temp1, temp0);
ST_W8(in0, in3, 0, 1, 2, 3, 0, 1, 2, 3, src, stride);
}
static void h263_v_loop_filter_msa(uint8_t *src, int32_t stride, int32_t qscale)
{
int32_t strength = h263_loop_filter_strength_msa[qscale];
uint64_t res0, res1, res2, res3;
v16u8 in0, in1, in2, in3;
v8i16 temp0, temp2, diff0, diff2, diff4, diff6, diff8;
v8i16 d0, a_d0, str_x2, str;
src -= 2 * stride;
LD_UB4(src, stride, in0, in3, in2, in1);
temp0 = (v8i16) __msa_ilvr_b((v16i8) in0, (v16i8) in1);
a_d0 = __msa_hsub_u_h((v16u8) temp0, (v16u8) temp0);
temp2 = (v8i16) __msa_ilvr_b((v16i8) in2, (v16i8) in3);
temp2 = __msa_hsub_u_h((v16u8) temp2, (v16u8) temp2);
temp2 <<= 2;
diff0 = a_d0 + temp2;
diff2 = -(-diff0 >> 3);
str_x2 = __msa_fill_h(-(strength << 1));
temp0 = (str_x2 <= diff2);
diff2 = (v8i16) __msa_bmz_v((v16u8) diff2, (v16u8) temp0, (v16u8) temp0);
temp2 = str_x2 - diff2;
str = __msa_fill_h(-strength);
temp0 = (diff2 < str);
diff2 = (v8i16) __msa_bmnz_v((v16u8) diff2, (v16u8) temp2, (v16u8) temp0);
diff4 = diff0 >> 3;
str_x2 = __msa_fill_h(strength << 1);
temp0 = (diff4 <= str_x2);
diff4 = (v8i16) __msa_bmz_v((v16u8) diff4, (v16u8) temp0, (v16u8) temp0);
temp2 = str_x2 - diff4;
str = __msa_fill_h(strength);
temp0 = (str < diff4);
diff4 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) temp2, (v16u8) temp0);
temp0 = __msa_clti_s_h(diff0, 0);
d0 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) diff2, (v16u8) temp0);
diff2 = -diff2 >> 1;
diff4 >>= 1;
diff8 = (v8i16) __msa_bmnz_v((v16u8) diff4, (v16u8) diff2, (v16u8) temp0);
diff6 = (-a_d0) >> 2;
diff6 = -(diff6);
temp2 = -diff8;
temp0 = (diff6 < temp2);
diff6 = (v8i16) __msa_bmnz_v((v16u8) diff6, (v16u8) temp2, (v16u8) temp0);
diff2 = a_d0 >> 2;
temp0 = (diff2 <= diff8);
diff2 = (v8i16) __msa_bmz_v((v16u8) diff2, (v16u8) diff8, (v16u8) temp0);
temp0 = __msa_clti_s_h(a_d0, 0);
diff6 = (v8i16) __msa_bmz_v((v16u8) diff6, (v16u8) diff2, (v16u8) temp0);
PCKEV_B2_SH(a_d0, diff6, a_d0, d0, diff6, d0);
in0 = (v16u8) ((v16i8) in0 - (v16i8) diff6);
in1 = (v16u8) ((v16i8) in1 + (v16i8) diff6);
in3 = __msa_xori_b(in3, 128);
in3 = (v16u8) __msa_adds_s_b((v16i8) in3, (v16i8) d0);
in3 = __msa_xori_b(in3, 128);
in2 = __msa_subsus_u_b(in2, (v16i8) d0);
res0 = __msa_copy_u_d((v2i64) in0, 0);
res1 = __msa_copy_u_d((v2i64) in3, 0);
res2 = __msa_copy_u_d((v2i64) in2, 0);
res3 = __msa_copy_u_d((v2i64) in1, 0);
SD4(res0, res1, res2, res3, src, stride);
}
void ff_h263_h_loop_filter_msa(uint8_t *src, int32_t stride, int32_t q_scale)
{
h263_h_loop_filter_msa(src, stride, q_scale);
}
void ff_h263_v_loop_filter_msa(uint8_t *src, int32_t stride, int32_t q_scale)
{
h263_v_loop_filter_msa(src, stride, q_scale);
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264chroma_mips.h"
#if HAVE_MSA
static av_cold void h264chroma_init_msa(H264ChromaContext *c, int bit_depth)
{
const int high_bit_depth = bit_depth > 8;
if (!high_bit_depth) {
c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_msa;
c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_msa;
c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_msa;
c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_msa;
c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_msa;
c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_msa;
}
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void h264chroma_init_mmi(H264ChromaContext *c, int bit_depth)
{
int high_bit_depth = bit_depth > 8;
if (!high_bit_depth) {
c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_mmi;
c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_mmi;
c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmi;
c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmi;
}
}
#endif /* HAVE_MMI */
av_cold void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth)
{
#if HAVE_MMI
h264chroma_init_mmi(c, bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264chroma_init_msa(c, bit_depth);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_H264CHROMA_MIPS_H
#define AVCODEC_MIPS_H264CHROMA_MIPS_H
#include "libavcodec/h264dec.h"
void ff_put_h264_chroma_mc8_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_put_h264_chroma_mc4_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_put_h264_chroma_mc2_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_avg_h264_chroma_mc8_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_avg_h264_chroma_mc4_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_avg_h264_chroma_mc2_msa(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int height, int x, int y);
void ff_put_h264_chroma_mc8_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_avg_h264_chroma_mc8_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_put_h264_chroma_mc4_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
void ff_avg_h264_chroma_mc4_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y);
#endif /* AVCODEC_MIPS_H264CHROMA_MIPS_H */

View File

@@ -0,0 +1,752 @@
/*
* Loongson SIMD optimized h264chroma
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
* Zhang Shuangshuang <zhangshuangshuang@ict.ac.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264chroma_mips.h"
#include "constants.h"
#include "libavutil/mips/mmiutils.h"
void ff_put_h264_chroma_mc8_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y)
{
int A = 64, B, C, D, E;
double ftmp[12];
uint64_t tmp[1];
if (!(x || y)) {
/* x=0, y=0, A=64 */
__asm__ volatile (
"1: \n\t"
MMI_ULDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp2], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp3], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x04 \n\t"
MMI_SDC1(%[ftmp0], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp3], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride)
: "memory"
);
} else if (x && y) {
/* x!=0, y!=0 */
D = x * y;
B = (x << 3) - D;
C = (y << 3) - D;
A = 64 - D - B - C;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[B], %[B], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp9] \n\t"
"pshufh %[C], %[C], %[ftmp0] \n\t"
"pshufh %[D], %[D], %[ftmp0] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
MMI_ULDC1(%[ftmp2], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp3], %[src], 0x00)
MMI_ULDC1(%[ftmp4], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp10], %[src], 0x00)
MMI_ULDC1(%[ftmp11], %[src], 0x01)
"addi %[h], %[h], -0x02 \n\t"
"punpcklbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[A] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[B] \n\t"
"paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[A] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[B] \n\t"
"paddh %[ftmp2], %[ftmp6], %[ftmp8] \n\t"
"punpcklbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp4], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[C] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[D] \n\t"
"paddh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[C] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[D] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp9] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"punpcklbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp4], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[A] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[B] \n\t"
"paddh %[ftmp3], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[A] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[B] \n\t"
"paddh %[ftmp4], %[ftmp6], %[ftmp8] \n\t"
"punpcklbh %[ftmp5], %[ftmp10], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp10], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp11], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp11], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[C] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[D] \n\t"
"paddh %[ftmp5], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[C] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[D] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ff_pw_32] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ff_pw_32] \n\t"
"psrlh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"psrlh %[ftmp4], %[ftmp4], %[ftmp9] \n\t"
"packushb %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp3], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]),
[tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [B]"f"(B),
[C]"f"(C), [D]"f"(D)
: "memory"
);
} else if (x) {
/* x!=0, y==0 */
E = x << 3;
A = 64 - E;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
MMI_ULDC1(%[ftmp2], %[src], 0x01)
"addi %[h], %[h], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[E] \n\t"
"paddh %[ftmp1], %[ftmp3], %[ftmp5] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[E] \n\t"
"paddh %[ftmp2], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
} else {
/* x==0, y!=0 */
E = y << 3;
A = 64 - E;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp2], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp8], %[src], 0x00)
"addi %[h], %[h], -0x02 \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[E] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[E] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ff_pw_32] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ff_pw_32] \n\t"
"psrlh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
"psrlh %[ftmp4], %[ftmp4], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp3], %[ftmp4] \n\t"
"punpcklbh %[ftmp3], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp2], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp8], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp8], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[E] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[E] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ff_pw_32] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ff_pw_32] \n\t"
"psrlh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
"psrlh %[ftmp4], %[ftmp4], %[ftmp7] \n\t"
"packushb %[ftmp2], %[ftmp3], %[ftmp4] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
}
}
void ff_avg_h264_chroma_mc8_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y)
{
int A = 64, B, C, D, E;
double ftmp[10];
uint64_t tmp[1];
if(!(x || y)){
/* x=0, y=0, A=64 */
__asm__ volatile (
"1: \n\t"
MMI_ULDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_LDC1(%[ftmp2], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_LDC1(%[ftmp3], %[dst], 0x00)
PTR_SUBU "%[dst], %[dst], %[stride] \n\t"
"pavgb %[ftmp0], %[ftmp0], %[ftmp2] \n\t"
"pavgb %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
MMI_SDC1(%[ftmp0], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"addi %[h], %[h], -0x02 \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride)
: "memory"
);
} else if (x && y) {
/* x!=0, y!=0 */
D = x * y;
B = (x << 3) - D;
C = (y << 3) - D;
A = 64 - D - B - C;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[B], %[B], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp9] \n\t"
"pshufh %[C], %[C], %[ftmp0] \n\t"
"pshufh %[D], %[D], %[ftmp0] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
MMI_ULDC1(%[ftmp2], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp3], %[src], 0x00)
MMI_ULDC1(%[ftmp4], %[src], 0x01)
"addi %[h], %[h], -0x01 \n\t"
"punpcklbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[A] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[B] \n\t"
"paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[A] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[B] \n\t"
"paddh %[ftmp2], %[ftmp6], %[ftmp8] \n\t"
"punpcklbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp7], %[ftmp4], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[C] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[D] \n\t"
"paddh %[ftmp3], %[ftmp5], %[ftmp7] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[C] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[D] \n\t"
"paddh %[ftmp4], %[ftmp6], %[ftmp8] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp9] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [B]"f"(B),
[C]"f"(C), [D]"f"(D)
: "memory"
);
} else if (x) {
/* x!=0, y==0 */
E = x << 3;
A = 64 - E;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
MMI_ULDC1(%[ftmp2], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x01 \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[E] \n\t"
"paddh %[ftmp1], %[ftmp3], %[ftmp5] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[E] \n\t"
"paddh %[ftmp2], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
} else {
/* x==0, y!=0 */
E = y << 3;
A = 64 - E;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"1: \n\t"
MMI_ULDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULDC1(%[ftmp2], %[src], 0x00)
"addi %[h], %[h], -0x01 \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[E] \n\t"
"paddh %[ftmp1], %[ftmp3], %[ftmp5] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[E] \n\t"
"paddh %[ftmp2], %[ftmp4], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_SDC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[tmp0]"=&r"(tmp[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
}
}
void ff_put_h264_chroma_mc4_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y)
{
const int A = (8 - x) * (8 - y);
const int B = x * (8 - y);
const int C = (8 - x) * y;
const int D = x * y;
const int E = B + C;
double ftmp[8];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_LOW32;
if (D) {
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[B], %[B], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"pshufh %[C], %[C], %[ftmp0] \n\t"
"pshufh %[D], %[D], %[ftmp0] \n\t"
"1: \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
MMI_ULWC1(%[ftmp2], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULWC1(%[ftmp3], %[src], 0x00)
MMI_ULWC1(%[ftmp4], %[src], 0x01)
"punpcklbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[B] \n\t"
"paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t"
"punpcklbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp6], %[ftmp4], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[C] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[D] \n\t"
"paddh %[ftmp2], %[ftmp5], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"addi %[h], %[h], -0x01 \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_LOW32
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [B]"f"(B),
[C]"f"(C), [D]"f"(D)
: "memory"
);
} else if (E) {
const int step = C ? stride : 1;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp5] \n\t"
"1: \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[addr0], %[src], %[step] \n\t"
MMI_ULWC1(%[ftmp2], %[addr0], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x01 \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp4], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[E] \n\t"
"paddh %[ftmp1], %[ftmp3], %[ftmp4] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_LOW32
[addr0]"=&r"(addr[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[step]"r"((mips_reg)step),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
} else {
__asm__ volatile (
"1: \n\t"
MMI_ULWC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x02 \n\t"
MMI_SWC1(%[ftmp0], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[dst]"+&r"(dst), [src]"+&r"(src),
RESTRICT_ASM_LOW32
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride)
: "memory"
);
}
}
void ff_avg_h264_chroma_mc4_mmi(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
int h, int x, int y)
{
const int A = (8 - x) *(8 - y);
const int B = x * (8 - y);
const int C = (8 - x) * y;
const int D = x * y;
const int E = B + C;
double ftmp[8];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_LOW32;
if (D) {
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[B], %[B], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp7] \n\t"
"pshufh %[C], %[C], %[ftmp0] \n\t"
"pshufh %[D], %[D], %[ftmp0] \n\t"
"1: \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
MMI_ULWC1(%[ftmp2], %[src], 0x01)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULWC1(%[ftmp3], %[src], 0x00)
MMI_ULWC1(%[ftmp4], %[src], 0x01)
"punpcklbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[A] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[B] \n\t"
"paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t"
"punpcklbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp6], %[ftmp4], %[ftmp0] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[C] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[D] \n\t"
"paddh %[ftmp2], %[ftmp5], %[ftmp6] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
MMI_LWC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"addi %[h], %[h], -0x01 \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_LOW32
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [B]"f"(B),
[C]"f"(C), [D]"f"(D)
: "memory"
);
} else if (E) {
const int step = C ? stride : 1;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x06 \n\t"
"pshufh %[A], %[A], %[ftmp0] \n\t"
"pshufh %[E], %[E], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp5] \n\t"
"1: \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[addr0], %[src], %[step] \n\t"
MMI_ULWC1(%[ftmp2], %[addr0], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x01 \n\t"
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp4], %[ftmp2], %[ftmp0] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[A] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[E] \n\t"
"paddh %[ftmp1], %[ftmp3], %[ftmp4] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ff_pw_32] \n\t"
"psrlh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
MMI_LWC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_LOW32
[addr0]"=&r"(addr[0]),
[dst]"+&r"(dst), [src]"+&r"(src),
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride),[step]"r"((mips_reg)step),
[ff_pw_32]"f"(ff_pw_32),
[A]"f"(A), [E]"f"(E)
: "memory"
);
} else {
__asm__ volatile (
"1: \n\t"
MMI_ULWC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_ULWC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"addi %[h], %[h], -0x02 \n\t"
MMI_LWC1(%[ftmp2], %[dst], 0x00)
"pavgb %[ftmp0], %[ftmp0], %[ftmp2] \n\t"
MMI_SWC1(%[ftmp0], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
MMI_LWC1(%[ftmp3], %[dst], 0x00)
"pavgb %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
MMI_SWC1(%[ftmp1], %[dst], 0x00)
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[dst]"+&r"(dst), [src]"+&r"(src),
RESTRICT_ASM_LOW32
[h]"+&r"(h)
: [stride]"r"((mips_reg)stride)
: "memory"
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264dsp_mips.h"
#if HAVE_MSA
static av_cold void h264dsp_init_msa(H264DSPContext *c,
const int bit_depth,
const int chroma_format_idc)
{
if (8 == bit_depth) {
c->h264_v_loop_filter_luma = ff_h264_v_lpf_luma_inter_msa;
c->h264_h_loop_filter_luma = ff_h264_h_lpf_luma_inter_msa;
c->h264_h_loop_filter_luma_mbaff =
ff_h264_h_loop_filter_luma_mbaff_msa;
c->h264_v_loop_filter_luma_intra = ff_h264_v_lpf_luma_intra_msa;
c->h264_h_loop_filter_luma_intra = ff_h264_h_lpf_luma_intra_msa;
c->h264_h_loop_filter_luma_mbaff_intra =
ff_h264_h_loop_filter_luma_mbaff_intra_msa;
c->h264_v_loop_filter_chroma = ff_h264_v_lpf_chroma_inter_msa;
if (chroma_format_idc <= 1)
c->h264_h_loop_filter_chroma = ff_h264_h_lpf_chroma_inter_msa;
else
c->h264_h_loop_filter_chroma =
ff_h264_h_loop_filter_chroma422_msa;
if (chroma_format_idc > 1)
c->h264_h_loop_filter_chroma_mbaff =
ff_h264_h_loop_filter_chroma422_mbaff_msa;
c->h264_v_loop_filter_chroma_intra =
ff_h264_v_lpf_chroma_intra_msa;
if (chroma_format_idc <= 1)
c->h264_h_loop_filter_chroma_intra =
ff_h264_h_lpf_chroma_intra_msa;
/* Weighted MC */
c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_8_msa;
c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_8_msa;
c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels4_8_msa;
c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_8_msa;
c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_8_msa;
c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels4_8_msa;
c->h264_idct_add = ff_h264_idct_add_msa;
c->h264_idct8_add = ff_h264_idct8_addblk_msa;
c->h264_idct_dc_add = ff_h264_idct4x4_addblk_dc_msa;
c->h264_idct8_dc_add = ff_h264_idct8_dc_addblk_msa;
c->h264_idct_add16 = ff_h264_idct_add16_msa;
c->h264_idct8_add4 = ff_h264_idct8_add4_msa;
if (chroma_format_idc <= 1)
c->h264_idct_add8 = ff_h264_idct_add8_msa;
else
c->h264_idct_add8 = ff_h264_idct_add8_422_msa;
c->h264_idct_add16intra = ff_h264_idct_add16_intra_msa;
c->h264_luma_dc_dequant_idct = ff_h264_deq_idct_luma_dc_msa;
} // if (8 == bit_depth)
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void h264dsp_init_mmi(H264DSPContext * c, const int bit_depth,
const int chroma_format_idc)
{
if (bit_depth == 8) {
c->h264_add_pixels4_clear = ff_h264_add_pixels4_8_mmi;
c->h264_idct_add = ff_h264_idct_add_8_mmi;
c->h264_idct8_add = ff_h264_idct8_add_8_mmi;
c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmi;
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmi;
c->h264_idct_add16 = ff_h264_idct_add16_8_mmi;
c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmi;
c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmi;
if (chroma_format_idc <= 1)
c->h264_idct_add8 = ff_h264_idct_add8_8_mmi;
else
c->h264_idct_add8 = ff_h264_idct_add8_422_8_mmi;
c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_8_mmi;
if (chroma_format_idc <= 1)
c->h264_chroma_dc_dequant_idct =
ff_h264_chroma_dc_dequant_idct_8_mmi;
else
c->h264_chroma_dc_dequant_idct =
ff_h264_chroma422_dc_dequant_idct_8_mmi;
c->weight_h264_pixels_tab[0] = ff_h264_weight_pixels16_8_mmi;
c->weight_h264_pixels_tab[1] = ff_h264_weight_pixels8_8_mmi;
c->weight_h264_pixels_tab[2] = ff_h264_weight_pixels4_8_mmi;
c->biweight_h264_pixels_tab[0] = ff_h264_biweight_pixels16_8_mmi;
c->biweight_h264_pixels_tab[1] = ff_h264_biweight_pixels8_8_mmi;
c->biweight_h264_pixels_tab[2] = ff_h264_biweight_pixels4_8_mmi;
c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmi;
c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmi;
if (chroma_format_idc <= 1) {
c->h264_h_loop_filter_chroma =
ff_deblock_h_chroma_8_mmi;
c->h264_h_loop_filter_chroma_intra =
ff_deblock_h_chroma_intra_8_mmi;
}
c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_mmi;
c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmi;
c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmi;
c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmi;
}
}
#endif /* HAVE_MMI */
av_cold void ff_h264dsp_init_mips(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc)
{
#if HAVE_MMI
h264dsp_init_mmi(c, bit_depth, chroma_format_idc);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264dsp_init_msa(c, bit_depth, chroma_format_idc);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,577 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_H264DSP_MIPS_H
#define AVCODEC_MIPS_H264DSP_MIPS_H
#include "libavcodec/h264dec.h"
#include "constants.h"
void ff_h264_h_lpf_luma_inter_msa(uint8_t *src, int stride,
int alpha, int beta, int8_t *tc0);
void ff_h264_v_lpf_luma_inter_msa(uint8_t *src, int stride,
int alpha, int beta, int8_t *tc0);
void ff_h264_h_lpf_chroma_inter_msa(uint8_t *src, int stride,
int alpha, int beta, int8_t *tc0);
void ff_h264_v_lpf_chroma_inter_msa(uint8_t *src, int stride,
int alpha, int beta, int8_t *tc0);
void ff_h264_h_loop_filter_chroma422_msa(uint8_t *src, int32_t stride,
int32_t alpha, int32_t beta,
int8_t *tc0);
void ff_h264_h_loop_filter_chroma422_mbaff_msa(uint8_t *src, int32_t stride,
int32_t alpha, int32_t beta,
int8_t *tc0);
void ff_h264_h_loop_filter_luma_mbaff_msa(uint8_t *src, int32_t stride,
int32_t alpha, int32_t beta,
int8_t *tc0);
void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride);
void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride);
void ff_h264_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
int32_t de_q_val);
void ff_h264_idct_add16_msa(uint8_t *dst, const int32_t *blk_offset,
int16_t *block, int32_t stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_idct_add16_intra_msa(uint8_t *dst, const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_idct_add8_msa(uint8_t **dst, const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_idct_add8_422_msa(uint8_t **dst, const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride);
void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride);
void ff_h264_idct8_add4_msa(uint8_t *dst, const int *blk_offset,
int16_t *blk, int dst_stride,
const uint8_t nnzc[15 * 8]);
void ff_h264_h_lpf_luma_intra_msa(uint8_t *src, int stride,
int alpha, int beta);
void ff_h264_v_lpf_luma_intra_msa(uint8_t *src, int stride,
int alpha, int beta);
void ff_h264_h_lpf_chroma_intra_msa(uint8_t *src, int stride,
int alpha, int beta);
void ff_h264_v_lpf_chroma_intra_msa(uint8_t *src, int stride,
int alpha, int beta);
void ff_h264_h_loop_filter_luma_mbaff_intra_msa(uint8_t *src, int stride,
int alpha, int beta);
void ff_biweight_h264_pixels16_8_msa(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom,
int weightd, int weights, int offset);
void ff_biweight_h264_pixels8_8_msa(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom,
int weightd, int weights, int offset);
void ff_biweight_h264_pixels4_8_msa(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom,
int weightd, int weights, int offset);
void ff_weight_h264_pixels16_8_msa(uint8_t *src, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_weight_h264_pixels8_8_msa(uint8_t *src, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_weight_h264_pixels4_8_msa(uint8_t *src, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_put_h264_qpel16_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc00_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc10_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc20_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc30_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc01_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc11_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc21_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc31_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc02_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc12_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc22_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc32_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc03_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc13_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc23_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc33_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_h264_intra_predict_plane_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_predict_dc_4blk_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_predict_hor_dc_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_predict_vert_dc_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_predict_mad_cow_dc_l0t_8x8_msa(uint8_t *src,
ptrdiff_t stride);
void ff_h264_intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src,
ptrdiff_t stride);
void ff_h264_intra_predict_mad_cow_dc_l00_8x8_msa(uint8_t *src,
ptrdiff_t stride);
void ff_h264_intra_predict_mad_cow_dc_0l0_8x8_msa(uint8_t *src,
ptrdiff_t stride);
void ff_h264_intra_predict_plane_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_vert_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_horiz_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_dc_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_vert_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_horiz_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_dc_left_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_dc_top_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_dc_128_8x8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_intra_pred_dc_128_16x16_msa(uint8_t *src, ptrdiff_t stride);
void ff_vp8_pred8x8_127_dc_8_msa(uint8_t *src, ptrdiff_t stride);
void ff_vp8_pred8x8_129_dc_8_msa(uint8_t *src, ptrdiff_t stride);
void ff_vp8_pred16x16_127_dc_8_msa(uint8_t *src, ptrdiff_t stride);
void ff_vp8_pred16x16_129_dc_8_msa(uint8_t *src, ptrdiff_t stride);
void ff_h264_add_pixels4_8_mmi(uint8_t *_dst, int16_t *_src, int stride);
void ff_h264_idct_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
void ff_h264_idct8_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
void ff_h264_idct_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
void ff_h264_idct8_dc_add_8_mmi(uint8_t *dst, int16_t *block, int stride);
void ff_h264_idct_add16_8_mmi(uint8_t *dst, const int *block_offset,
int16_t *block, int stride, const uint8_t nnzc[15*8]);
void ff_h264_idct_add16intra_8_mmi(uint8_t *dst, const int *block_offset,
int16_t *block, int stride, const uint8_t nnzc[15*8]);
void ff_h264_idct8_add4_8_mmi(uint8_t *dst, const int *block_offset,
int16_t *block, int stride, const uint8_t nnzc[15*8]);
void ff_h264_idct_add8_8_mmi(uint8_t **dest, const int *block_offset,
int16_t *block, int stride, const uint8_t nnzc[15*8]);
void ff_h264_idct_add8_422_8_mmi(uint8_t **dest, const int *block_offset,
int16_t *block, int stride, const uint8_t nnzc[15*8]);
void ff_h264_luma_dc_dequant_idct_8_mmi(int16_t *output, int16_t *input,
int qmul);
void ff_h264_chroma_dc_dequant_idct_8_mmi(int16_t *block, int qmul);
void ff_h264_chroma422_dc_dequant_idct_8_mmi(int16_t *block, int qmul);
void ff_h264_weight_pixels16_8_mmi(uint8_t *block, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_h264_biweight_pixels16_8_mmi(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom, int weightd, int weights,
int offset);
void ff_h264_weight_pixels8_8_mmi(uint8_t *block, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_h264_biweight_pixels8_8_mmi(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom, int weightd, int weights,
int offset);
void ff_h264_weight_pixels4_8_mmi(uint8_t *block, ptrdiff_t stride, int height,
int log2_denom, int weight, int offset);
void ff_h264_biweight_pixels4_8_mmi(uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int height, int log2_denom, int weightd, int weights,
int offset);
void ff_deblock_v_chroma_8_mmi(uint8_t *pix, ptrdiff_t stride, int alpha, int beta,
int8_t *tc0);
void ff_deblock_v_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha,
int beta);
void ff_deblock_h_chroma_8_mmi(uint8_t *pix, int stride, int alpha, int beta,
int8_t *tc0);
void ff_deblock_h_chroma_intra_8_mmi(uint8_t *pix, int stride, int alpha,
int beta);
void ff_deblock_v_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta,
int8_t *tc0);
void ff_deblock_v_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha,
int beta);
void ff_deblock_h_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta,
int8_t *tc0);
void ff_deblock_h_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha,
int beta);
void ff_deblock_v8_luma_8_mmi(uint8_t *pix, int stride, int alpha, int beta,
int8_t *tc0);
void ff_deblock_v8_luma_intra_8_mmi(uint8_t *pix, int stride, int alpha,
int beta);
void ff_put_h264_qpel16_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel16_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel8_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_put_h264_qpel4_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel16_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel8_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
void ff_avg_h264_qpel4_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride);
#endif // #ifndef AVCODEC_MIPS_H264DSP_MIPS_H

2726
externals/ffmpeg/libavcodec/mips/h264dsp_mmi.c vendored Executable file

File diff suppressed because it is too large Load Diff

2594
externals/ffmpeg/libavcodec/mips/h264dsp_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,470 @@
/*
* Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "h264dsp_mips.h"
#include "libavcodec/bit_depth_template.c"
#define AVC_ITRANS_H(in0, in1, in2, in3, out0, out1, out2, out3) \
{ \
v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \
\
tmp0_m = in0 + in2; \
tmp1_m = in0 - in2; \
tmp2_m = in1 >> 1; \
tmp2_m = tmp2_m - in3; \
tmp3_m = in3 >> 1; \
tmp3_m = in1 + tmp3_m; \
\
BUTTERFLY_4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, out0, out1, out2, out3); \
}
static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
int32_t de_q_val)
{
#define DC_DEST_STRIDE 16
int16_t out0, out1, out2, out3, out4, out5, out6, out7;
v8i16 src1, src3;
v8i16 vec0, vec1, vec2, vec3;
v8i16 tmp0, tmp1, tmp2, tmp3;
v8i16 hres0, hres1, hres2, hres3;
v8i16 vres0, vres1, vres2, vres3;
v4i32 vres0_r, vres1_r, vres2_r, vres3_r;
const v4i32 de_q_vec = __msa_fill_w(de_q_val);
const v8i16 src0 = LD_SH(src);
const v8i16 src2 = LD_SH(src + 8);
ILVL_D2_SH(src0, src0, src2, src2, src1, src3);
TRANSPOSE4x4_SH_SH(src0, src1, src2, src3, tmp0, tmp1, tmp2, tmp3);
BUTTERFLY_4(tmp0, tmp2, tmp3, tmp1, vec0, vec3, vec2, vec1);
BUTTERFLY_4(vec0, vec1, vec2, vec3, hres0, hres3, hres2, hres1);
TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3);
BUTTERFLY_4(hres0, hres1, hres3, hres2, vec0, vec3, vec2, vec1);
BUTTERFLY_4(vec0, vec1, vec2, vec3, vres0, vres1, vres2, vres3);
UNPCK_R_SH_SW(vres0, vres0_r);
UNPCK_R_SH_SW(vres1, vres1_r);
UNPCK_R_SH_SW(vres2, vres2_r);
UNPCK_R_SH_SW(vres3, vres3_r);
vres0_r *= de_q_vec;
vres1_r *= de_q_vec;
vres2_r *= de_q_vec;
vres3_r *= de_q_vec;
SRARI_W4_SW(vres0_r, vres1_r, vres2_r, vres3_r, 8);
PCKEV_H2_SH(vres1_r, vres0_r, vres3_r, vres2_r, vec0, vec1);
out0 = __msa_copy_s_h(vec0, 0);
out1 = __msa_copy_s_h(vec0, 1);
out2 = __msa_copy_s_h(vec0, 2);
out3 = __msa_copy_s_h(vec0, 3);
out4 = __msa_copy_s_h(vec0, 4);
out5 = __msa_copy_s_h(vec0, 5);
out6 = __msa_copy_s_h(vec0, 6);
out7 = __msa_copy_s_h(vec0, 7);
SH(out0, (dst + 0 * DC_DEST_STRIDE));
SH(out1, (dst + 2 * DC_DEST_STRIDE));
SH(out2, (dst + 8 * DC_DEST_STRIDE));
SH(out3, (dst + 10 * DC_DEST_STRIDE));
SH(out4, (dst + 1 * DC_DEST_STRIDE));
SH(out5, (dst + 3 * DC_DEST_STRIDE));
SH(out6, (dst + 9 * DC_DEST_STRIDE));
SH(out7, (dst + 11 * DC_DEST_STRIDE));
out0 = __msa_copy_s_h(vec1, 0);
out1 = __msa_copy_s_h(vec1, 1);
out2 = __msa_copy_s_h(vec1, 2);
out3 = __msa_copy_s_h(vec1, 3);
out4 = __msa_copy_s_h(vec1, 4);
out5 = __msa_copy_s_h(vec1, 5);
out6 = __msa_copy_s_h(vec1, 6);
out7 = __msa_copy_s_h(vec1, 7);
SH(out0, (dst + 4 * DC_DEST_STRIDE));
SH(out1, (dst + 6 * DC_DEST_STRIDE));
SH(out2, (dst + 12 * DC_DEST_STRIDE));
SH(out3, (dst + 14 * DC_DEST_STRIDE));
SH(out4, (dst + 5 * DC_DEST_STRIDE));
SH(out5, (dst + 7 * DC_DEST_STRIDE));
SH(out6, (dst + 13 * DC_DEST_STRIDE));
SH(out7, (dst + 15 * DC_DEST_STRIDE));
#undef DC_DEST_STRIDE
}
static void avc_idct8_addblk_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
{
v8i16 src0, src1, src2, src3, src4, src5, src6, src7;
v8i16 vec0, vec1, vec2, vec3;
v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
v8i16 res0, res1, res2, res3, res4, res5, res6, res7;
v4i32 tmp0_r, tmp1_r, tmp2_r, tmp3_r, tmp4_r, tmp5_r, tmp6_r, tmp7_r;
v4i32 tmp0_l, tmp1_l, tmp2_l, tmp3_l, tmp4_l, tmp5_l, tmp6_l, tmp7_l;
v4i32 vec0_r, vec1_r, vec2_r, vec3_r, vec0_l, vec1_l, vec2_l, vec3_l;
v4i32 res0_r, res1_r, res2_r, res3_r, res4_r, res5_r, res6_r, res7_r;
v4i32 res0_l, res1_l, res2_l, res3_l, res4_l, res5_l, res6_l, res7_l;
v16i8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
v8i16 zeros = { 0 };
src[0] += 32;
LD_SH8(src, 8, src0, src1, src2, src3, src4, src5, src6, src7);
ST_SH8(zeros, zeros, zeros, zeros, zeros, zeros, zeros, zeros, src, 8);
vec0 = src0 + src4;
vec1 = src0 - src4;
vec2 = src2 >> 1;
vec2 = vec2 - src6;
vec3 = src6 >> 1;
vec3 = src2 + vec3;
BUTTERFLY_4(vec0, vec1, vec2, vec3, tmp0, tmp1, tmp2, tmp3);
vec0 = src7 >> 1;
vec0 = src5 - vec0 - src3 - src7;
vec1 = src3 >> 1;
vec1 = src1 - vec1 + src7 - src3;
vec2 = src5 >> 1;
vec2 = vec2 - src1 + src7 + src5;
vec3 = src1 >> 1;
vec3 = vec3 + src3 + src5 + src1;
tmp4 = vec3 >> 2;
tmp4 += vec0;
tmp5 = vec2 >> 2;
tmp5 += vec1;
tmp6 = vec1 >> 2;
tmp6 -= vec2;
tmp7 = vec0 >> 2;
tmp7 = vec3 - tmp7;
BUTTERFLY_8(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7,
res0, res1, res2, res3, res4, res5, res6, res7);
TRANSPOSE8x8_SH_SH(res0, res1, res2, res3, res4, res5, res6, res7,
res0, res1, res2, res3, res4, res5, res6, res7);
UNPCK_SH_SW(res0, tmp0_r, tmp0_l);
UNPCK_SH_SW(res1, tmp1_r, tmp1_l);
UNPCK_SH_SW(res2, tmp2_r, tmp2_l);
UNPCK_SH_SW(res3, tmp3_r, tmp3_l);
UNPCK_SH_SW(res4, tmp4_r, tmp4_l);
UNPCK_SH_SW(res5, tmp5_r, tmp5_l);
UNPCK_SH_SW(res6, tmp6_r, tmp6_l);
UNPCK_SH_SW(res7, tmp7_r, tmp7_l);
BUTTERFLY_4(tmp0_r, tmp0_l, tmp4_l, tmp4_r, vec0_r, vec0_l, vec1_l, vec1_r);
vec2_r = tmp2_r >> 1;
vec2_l = tmp2_l >> 1;
vec2_r -= tmp6_r;
vec2_l -= tmp6_l;
vec3_r = tmp6_r >> 1;
vec3_l = tmp6_l >> 1;
vec3_r += tmp2_r;
vec3_l += tmp2_l;
BUTTERFLY_4(vec0_r, vec1_r, vec2_r, vec3_r, tmp0_r, tmp2_r, tmp4_r, tmp6_r);
BUTTERFLY_4(vec0_l, vec1_l, vec2_l, vec3_l, tmp0_l, tmp2_l, tmp4_l, tmp6_l);
vec0_r = tmp7_r >> 1;
vec0_l = tmp7_l >> 1;
vec0_r = tmp5_r - vec0_r - tmp3_r - tmp7_r;
vec0_l = tmp5_l - vec0_l - tmp3_l - tmp7_l;
vec1_r = tmp3_r >> 1;
vec1_l = tmp3_l >> 1;
vec1_r = tmp1_r - vec1_r + tmp7_r - tmp3_r;
vec1_l = tmp1_l - vec1_l + tmp7_l - tmp3_l;
vec2_r = tmp5_r >> 1;
vec2_l = tmp5_l >> 1;
vec2_r = vec2_r - tmp1_r + tmp7_r + tmp5_r;
vec2_l = vec2_l - tmp1_l + tmp7_l + tmp5_l;
vec3_r = tmp1_r >> 1;
vec3_l = tmp1_l >> 1;
vec3_r = vec3_r + tmp3_r + tmp5_r + tmp1_r;
vec3_l = vec3_l + tmp3_l + tmp5_l + tmp1_l;
tmp1_r = vec3_r >> 2;
tmp1_l = vec3_l >> 2;
tmp1_r += vec0_r;
tmp1_l += vec0_l;
tmp3_r = vec2_r >> 2;
tmp3_l = vec2_l >> 2;
tmp3_r += vec1_r;
tmp3_l += vec1_l;
tmp5_r = vec1_r >> 2;
tmp5_l = vec1_l >> 2;
tmp5_r -= vec2_r;
tmp5_l -= vec2_l;
tmp7_r = vec0_r >> 2;
tmp7_l = vec0_l >> 2;
tmp7_r = vec3_r - tmp7_r;
tmp7_l = vec3_l - tmp7_l;
BUTTERFLY_4(tmp0_r, tmp0_l, tmp7_l, tmp7_r, res0_r, res0_l, res7_l, res7_r);
BUTTERFLY_4(tmp2_r, tmp2_l, tmp5_l, tmp5_r, res1_r, res1_l, res6_l, res6_r);
BUTTERFLY_4(tmp4_r, tmp4_l, tmp3_l, tmp3_r, res2_r, res2_l, res5_l, res5_r);
BUTTERFLY_4(tmp6_r, tmp6_l, tmp1_l, tmp1_r, res3_r, res3_l, res4_l, res4_r);
SRA_4V(res0_r, res0_l, res1_r, res1_l, 6);
SRA_4V(res2_r, res2_l, res3_r, res3_l, 6);
SRA_4V(res4_r, res4_l, res5_r, res5_l, 6);
SRA_4V(res6_r, res6_l, res7_r, res7_l, 6);
PCKEV_H4_SH(res0_l, res0_r, res1_l, res1_r, res2_l, res2_r, res3_l, res3_r,
res0, res1, res2, res3);
PCKEV_H4_SH(res4_l, res4_r, res5_l, res5_r, res6_l, res6_r, res7_l, res7_r,
res4, res5, res6, res7);
LD_SB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7);
ILVR_B4_SH(zeros, dst0, zeros, dst1, zeros, dst2, zeros, dst3,
tmp0, tmp1, tmp2, tmp3);
ILVR_B4_SH(zeros, dst4, zeros, dst5, zeros, dst6, zeros, dst7,
tmp4, tmp5, tmp6, tmp7);
ADD4(res0, tmp0, res1, tmp1, res2, tmp2, res3, tmp3,
res0, res1, res2, res3);
ADD4(res4, tmp4, res5, tmp5, res6, tmp6, res7, tmp7,
res4, res5, res6, res7);
CLIP_SH8_0_255(res0, res1, res2, res3, res4, res5, res6, res7);
PCKEV_B4_SB(res1, res0, res3, res2, res5, res4, res7, res6,
dst0, dst1, dst2, dst3);
ST_D8(dst0, dst1, dst2, dst3, 0, 1, 0, 1, 0, 1, 0, 1, dst, dst_stride)
}
static void avc_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride)
{
int32_t dc_val;
v16i8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
v8i16 dst0_r, dst1_r, dst2_r, dst3_r, dst4_r, dst5_r, dst6_r, dst7_r;
v8i16 dc;
v16i8 zeros = { 0 };
dc_val = (src[0] + 32) >> 6;
dc = __msa_fill_h(dc_val);
src[0] = 0;
LD_SB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7);
ILVR_B4_SH(zeros, dst0, zeros, dst1, zeros, dst2, zeros, dst3,
dst0_r, dst1_r, dst2_r, dst3_r);
ILVR_B4_SH(zeros, dst4, zeros, dst5, zeros, dst6, zeros, dst7,
dst4_r, dst5_r, dst6_r, dst7_r);
ADD4(dst0_r, dc, dst1_r, dc, dst2_r, dc, dst3_r, dc,
dst0_r, dst1_r, dst2_r, dst3_r);
ADD4(dst4_r, dc, dst5_r, dc, dst6_r, dc, dst7_r, dc,
dst4_r, dst5_r, dst6_r, dst7_r);
CLIP_SH8_0_255(dst0_r, dst1_r, dst2_r, dst3_r,
dst4_r, dst5_r, dst6_r, dst7_r);
PCKEV_B4_SB(dst1_r, dst0_r, dst3_r, dst2_r, dst5_r, dst4_r, dst7_r, dst6_r,
dst0, dst1, dst2, dst3);
ST_D8(dst0, dst1, dst2, dst3, 0, 1, 0, 1, 0, 1, 0, 1, dst, dst_stride)
}
void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
{
uint32_t src0_m, src1_m, src2_m, src3_m, out0_m, out1_m, out2_m, out3_m;
v16i8 dst0_m = { 0 };
v16i8 dst1_m = { 0 };
v8i16 hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3;
v8i16 inp0_m, inp1_m, res0_m, res1_m, src1, src3;
const v8i16 src0 = LD_SH(src);
const v8i16 src2 = LD_SH(src + 8);
const v8i16 zero = { 0 };
const uint8_t *dst1 = dst + dst_stride;
const uint8_t *dst2 = dst + 2 * dst_stride;
const uint8_t *dst3 = dst + 3 * dst_stride;
ILVL_D2_SH(src0, src0, src2, src2, src1, src3);
ST_SH2(zero, zero, src, 8);
AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3);
TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3);
AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3);
src0_m = LW(dst);
src1_m = LW(dst1);
SRARI_H4_SH(vres0, vres1, vres2, vres3, 6);
src2_m = LW(dst2);
src3_m = LW(dst3);
ILVR_D2_SH(vres1, vres0, vres3, vres2, inp0_m, inp1_m);
INSERT_W2_SB(src0_m, src1_m, dst0_m);
INSERT_W2_SB(src2_m, src3_m, dst1_m);
ILVR_B2_SH(zero, dst0_m, zero, dst1_m, res0_m, res1_m);
ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m);
CLIP_SH2_0_255(res0_m, res1_m);
PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m);
out0_m = __msa_copy_u_w((v4i32) dst0_m, 0);
out1_m = __msa_copy_u_w((v4i32) dst0_m, 1);
out2_m = __msa_copy_u_w((v4i32) dst1_m, 0);
out3_m = __msa_copy_u_w((v4i32) dst1_m, 1);
SW(out0_m, dst);
SW(out1_m, dst1);
SW(out2_m, dst2);
SW(out3_m, dst3);
}
void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride)
{
avc_idct8_addblk_msa(dst, src, dst_stride);
}
void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride)
{
v16u8 pred = { 0 };
v16i8 out;
v8i16 pred_r, pred_l;
const uint32_t src0 = LW(dst);
const uint32_t src1 = LW(dst + dst_stride);
const uint32_t src2 = LW(dst + 2 * dst_stride);
const uint32_t src3 = LW(dst + 3 * dst_stride);
const int16_t dc = (src[0] + 32) >> 6;
const v8i16 input_dc = __msa_fill_h(dc);
src[0] = 0;
INSERT_W4_UB(src0, src1, src2, src3, pred);
UNPCK_UB_SH(pred, pred_r, pred_l);
ADD2(pred_r, input_dc, pred_l, input_dc, pred_r, pred_l);
CLIP_SH2_0_255(pred_r, pred_l);
out = __msa_pckev_b((v16i8) pred_l, (v16i8) pred_r);
ST_W4(out, 0, 1, 2, 3, dst, dst_stride);
}
void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride)
{
avc_idct8_dc_addblk_msa(dst, src, dst_stride);
}
void ff_h264_idct_add16_msa(uint8_t *dst,
const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
for (i = 0; i < 16; i++) {
int32_t nnz = nzc[scan8[i]];
if (nnz) {
if (nnz == 1 && ((dctcoef *) block)[i * 16])
ff_h264_idct4x4_addblk_dc_msa(dst + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
else
ff_h264_idct_add_msa(dst + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
}
}
}
void ff_h264_idct8_add4_msa(uint8_t *dst, const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t cnt;
for (cnt = 0; cnt < 16; cnt += 4) {
int32_t nnz = nzc[scan8[cnt]];
if (nnz) {
if (nnz == 1 && ((dctcoef *) block)[cnt * 16])
ff_h264_idct8_dc_addblk_msa(dst + blk_offset[cnt],
block + cnt * 16 * sizeof(pixel),
dst_stride);
else
ff_h264_idct8_addblk_msa(dst + blk_offset[cnt],
block + cnt * 16 * sizeof(pixel),
dst_stride);
}
}
}
void ff_h264_idct_add8_msa(uint8_t **dst,
const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i, j;
for (j = 1; j < 3; j++) {
for (i = (j * 16); i < (j * 16 + 4); i++) {
if (nzc[scan8[i]])
ff_h264_idct_add_msa(dst[j - 1] + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
else if (((dctcoef *) block)[i * 16])
ff_h264_idct4x4_addblk_dc_msa(dst[j - 1] + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
}
}
}
void ff_h264_idct_add8_422_msa(uint8_t **dst,
const int32_t *blk_offset,
int16_t *block, int32_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i, j;
for (j = 1; j < 3; j++) {
for (i = (j * 16); i < (j * 16 + 4); i++) {
if (nzc[scan8[i]])
ff_h264_idct_add_msa(dst[j - 1] + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
else if (((dctcoef *) block)[i * 16])
ff_h264_idct4x4_addblk_dc_msa(dst[j - 1] + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
}
}
for (j = 1; j < 3; j++) {
for (i = (j * 16 + 4); i < (j * 16 + 8); i++) {
if (nzc[scan8[i + 4]])
ff_h264_idct_add_msa(dst[j - 1] + blk_offset[i + 4],
block + i * 16 * sizeof(pixel),
dst_stride);
else if (((dctcoef *) block)[i * 16])
ff_h264_idct4x4_addblk_dc_msa(dst[j - 1] + blk_offset[i + 4],
block + i * 16 * sizeof(pixel),
dst_stride);
}
}
}
void ff_h264_idct_add16_intra_msa(uint8_t *dst,
const int32_t *blk_offset,
int16_t *block,
int32_t dst_stride,
const uint8_t nzc[15 * 8])
{
int32_t i;
for (i = 0; i < 16; i++) {
if (nzc[scan8[i]])
ff_h264_idct_add_msa(dst + blk_offset[i],
block + i * 16 * sizeof(pixel), dst_stride);
else if (((dctcoef *) block)[i * 16])
ff_h264_idct4x4_addblk_dc_msa(dst + blk_offset[i],
block + i * 16 * sizeof(pixel),
dst_stride);
}
}
void ff_h264_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
int32_t de_qval)
{
avc_deq_idct_luma_dc_msa(dst, src, de_qval);
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "h264dsp_mips.h"
#include "h264pred_mips.h"
#if HAVE_MSA
static av_cold void h264_pred_init_msa(H264PredContext *h, int codec_id,
const int bit_depth,
const int chroma_format_idc)
{
if (8 == bit_depth) {
if (chroma_format_idc == 1) {
h->pred8x8[VERT_PRED8x8] = ff_h264_intra_pred_vert_8x8_msa;
h->pred8x8[HOR_PRED8x8] = ff_h264_intra_pred_horiz_8x8_msa;
}
if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) {
if (chroma_format_idc == 1) {
h->pred8x8[PLANE_PRED8x8] = ff_h264_intra_predict_plane_8x8_msa;
}
}
if (codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP7
&& codec_id != AV_CODEC_ID_VP8) {
if (chroma_format_idc == 1) {
h->pred8x8[DC_PRED8x8] = ff_h264_intra_predict_dc_4blk_8x8_msa;
h->pred8x8[LEFT_DC_PRED8x8] =
ff_h264_intra_predict_hor_dc_8x8_msa;
h->pred8x8[TOP_DC_PRED8x8] =
ff_h264_intra_predict_vert_dc_8x8_msa;
h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8] =
ff_h264_intra_predict_mad_cow_dc_l0t_8x8_msa;
h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8] =
ff_h264_intra_predict_mad_cow_dc_0lt_8x8_msa;
h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] =
ff_h264_intra_predict_mad_cow_dc_l00_8x8_msa;
h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] =
ff_h264_intra_predict_mad_cow_dc_0l0_8x8_msa;
}
} else {
if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) {
h->pred8x8[7] = ff_vp8_pred8x8_127_dc_8_msa;
h->pred8x8[8] = ff_vp8_pred8x8_129_dc_8_msa;
}
}
if (chroma_format_idc == 1) {
h->pred8x8[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_8x8_msa;
}
h->pred16x16[DC_PRED8x8] = ff_h264_intra_pred_dc_16x16_msa;
h->pred16x16[VERT_PRED8x8] = ff_h264_intra_pred_vert_16x16_msa;
h->pred16x16[HOR_PRED8x8] = ff_h264_intra_pred_horiz_16x16_msa;
switch (codec_id) {
case AV_CODEC_ID_SVQ3:
case AV_CODEC_ID_RV40:
break;
case AV_CODEC_ID_VP7:
case AV_CODEC_ID_VP8:
h->pred16x16[7] = ff_vp8_pred16x16_127_dc_8_msa;
h->pred16x16[8] = ff_vp8_pred16x16_129_dc_8_msa;
break;
default:
h->pred16x16[PLANE_PRED8x8] =
ff_h264_intra_predict_plane_16x16_msa;
break;
}
h->pred16x16[LEFT_DC_PRED8x8] = ff_h264_intra_pred_dc_left_16x16_msa;
h->pred16x16[TOP_DC_PRED8x8] = ff_h264_intra_pred_dc_top_16x16_msa;
h->pred16x16[DC_128_PRED8x8] = ff_h264_intra_pred_dc_128_16x16_msa;
}
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void h264_pred_init_mmi(H264PredContext *h, int codec_id,
const int bit_depth, const int chroma_format_idc)
{
if (bit_depth == 8) {
if (chroma_format_idc == 1) {
h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmi;
h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmi;
} else {
h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x16_vertical_8_mmi;
h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x16_horizontal_8_mmi;
}
h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmi;
h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmi;
h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmi;
h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmi;
h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmi;
#if ARCH_MIPS64
switch (codec_id) {
case AV_CODEC_ID_SVQ3:
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmi;
break;
case AV_CODEC_ID_RV40:
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_rv40_8_mmi;
break;
case AV_CODEC_ID_VP7:
case AV_CODEC_ID_VP8:
break;
default:
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_h264_8_mmi;
break;
}
#endif
if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) {
if (chroma_format_idc == 1) {
h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmi;
h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmi;
}
}
}
}
#endif /* HAVE_MMI */
av_cold void ff_h264_pred_init_mips(H264PredContext *h, int codec_id,
int bit_depth,
const int chroma_format_idc)
{
#if HAVE_MMI
h264_pred_init_mmi(h, codec_id, bit_depth, chroma_format_idc);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264_pred_init_msa(h, codec_id, bit_depth, chroma_format_idc);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_H264PRED_MIPS_H
#define AVCODEC_MIPS_H264PRED_MIPS_H
#include "constants.h"
#include "libavcodec/h264pred.h"
void ff_pred16x16_vertical_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred16x16_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred16x16_dc_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x8l_top_dc_8_mmi(uint8_t *src, int has_topleft, int has_topright,
ptrdiff_t stride);
void ff_pred8x8l_dc_8_mmi(uint8_t *src, int has_topleft, int has_topright,
ptrdiff_t stride);
void ff_pred8x8l_vertical_8_mmi(uint8_t *src, int has_topleft,
int has_topright, ptrdiff_t stride);
void ff_pred4x4_dc_8_mmi(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride);
void ff_pred8x8_vertical_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x8_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred16x16_plane_svq3_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred16x16_plane_rv40_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred16x16_plane_h264_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x8_top_dc_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x8_dc_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x16_vertical_8_mmi(uint8_t *src, ptrdiff_t stride);
void ff_pred8x16_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride);
#endif /* AVCODEC_MIPS_H264PRED_MIPS_H */

View File

@@ -0,0 +1,985 @@
/*
* Loongson SIMD optimized h264pred
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
* Zhang Shuangshuang <zhangshuangshuang@ict.ac.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264pred_mips.h"
#include "libavcodec/bit_depth_template.c"
#include "libavutil/mips/mmiutils.h"
#include "constants.h"
void ff_pred16x16_vertical_8_mmi(uint8_t *src, ptrdiff_t stride)
{
double ftmp[2];
uint64_t tmp[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
"dli %[tmp0], 0x08 \n\t"
MMI_LDC1(%[ftmp0], %[srcA], 0x00)
MMI_LDC1(%[ftmp1], %[srcA], 0x08)
"1: \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDC1(%[ftmp1], %[src], 0x08)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDC1(%[ftmp1], %[src], 0x08)
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[src]"+&r"(src)
: [stride]"r"((mips_reg)stride), [srcA]"r"((mips_reg)(src-stride))
: "memory"
);
}
void ff_pred16x16_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride)
{
uint64_t tmp[3];
mips_reg addr[2];
__asm__ volatile (
PTR_ADDI "%[addr0], %[src], -0x01 \n\t"
PTR_ADDU "%[addr1], %[src], $0 \n\t"
"dli %[tmp2], 0x08 \n\t"
"1: \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"dmul %[tmp1], %[tmp0], %[ff_pb_1] \n\t"
"swl %[tmp1], 0x07(%[addr1]) \n\t"
"swr %[tmp1], 0x00(%[addr1]) \n\t"
"swl %[tmp1], 0x0f(%[addr1]) \n\t"
"swr %[tmp1], 0x08(%[addr1]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"dmul %[tmp1], %[tmp0], %[ff_pb_1] \n\t"
"swl %[tmp1], 0x07(%[addr1]) \n\t"
"swr %[tmp1], 0x00(%[addr1]) \n\t"
"swl %[tmp1], 0x0f(%[addr1]) \n\t"
"swr %[tmp1], 0x08(%[addr1]) \n\t"
"daddi %[tmp2], %[tmp2], -0x01 \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"bnez %[tmp2], 1b \n\t"
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[tmp2]"=&r"(tmp[2]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride),
[ff_pb_1]"r"(ff_pb_1)
: "memory"
);
}
void ff_pred16x16_dc_8_mmi(uint8_t *src, ptrdiff_t stride)
{
uint64_t tmp[4];
mips_reg addr[2];
__asm__ volatile (
PTR_ADDI "%[addr0], %[src], -0x01 \n\t"
"dli %[tmp0], 0x08 \n\t"
"xor %[tmp3], %[tmp3], %[tmp3] \n\t"
"1: \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"daddu %[tmp3], %[tmp3], %[tmp1] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
"daddu %[tmp3], %[tmp3], %[tmp1] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
"dli %[tmp0], 0x08 \n\t"
PTR_SUBU "%[addr0], %[src], %[stride] \n\t"
"2: \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"daddu %[tmp3], %[tmp3], %[tmp1] \n\t"
PTR_ADDIU "%[addr0], %[addr0], 0x01 \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
"daddu %[tmp3], %[tmp3], %[tmp1] \n\t"
PTR_ADDIU "%[addr0], %[addr0], 0x01 \n\t"
"bnez %[tmp0], 2b \n\t"
"daddiu %[tmp3], %[tmp3], 0x10 \n\t"
"dsra %[tmp3], 0x05 \n\t"
"dmul %[tmp2], %[tmp3], %[ff_pb_1] \n\t"
PTR_ADDU "%[addr0], %[src], $0 \n\t"
"dli %[tmp0], 0x08 \n\t"
"3: \n\t"
"swl %[tmp2], 0x07(%[addr0]) \n\t"
"swr %[tmp2], 0x00(%[addr0]) \n\t"
"swl %[tmp2], 0x0f(%[addr0]) \n\t"
"swr %[tmp2], 0x08(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"swl %[tmp2], 0x07(%[addr0]) \n\t"
"swr %[tmp2], 0x00(%[addr0]) \n\t"
"swl %[tmp2], 0x0f(%[addr0]) \n\t"
"swr %[tmp2], 0x08(%[addr0]) \n\t"
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"bnez %[tmp0], 3b \n\t"
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[tmp2]"=&r"(tmp[2]), [tmp3]"=&r"(tmp[3]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride),
[ff_pb_1]"r"(ff_pb_1)
: "memory"
);
}
void ff_pred8x8l_top_dc_8_mmi(uint8_t *src, int has_topleft,
int has_topright, ptrdiff_t stride)
{
uint32_t dc;
double ftmp[11];
mips_reg tmp[3];
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
MMI_ULDC1(%[ftmp10], %[srcA], 0x00)
MMI_ULDC1(%[ftmp9], %[src0], 0x00)
MMI_ULDC1(%[ftmp8], %[src1], 0x00)
"punpcklbh %[ftmp7], %[ftmp10], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp10], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp9], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp9], %[ftmp0] \n\t"
"punpcklbh %[ftmp3], %[ftmp8], %[ftmp0] \n\t"
"punpckhbh %[ftmp2], %[ftmp8], %[ftmp0] \n\t"
"bnez %[has_topleft], 1f \n\t"
"pinsrh_0 %[ftmp7], %[ftmp7], %[ftmp5] \n\t"
"1: \n\t"
"bnez %[has_topright], 2f \n\t"
"pinsrh_3 %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"2: \n\t"
"dli %[tmp0], 0x02 \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"pmullh %[ftmp5], %[ftmp5], %[ff_pw_2] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[ff_pw_2] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp5] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp4] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp3] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ff_pw_2] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ff_pw_2] \n\t"
"psrah %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"psrah %[ftmp6], %[ftmp6], %[ftmp1] \n\t"
"packushb %[ftmp9], %[ftmp7], %[ftmp6] \n\t"
"biadd %[ftmp10], %[ftmp9] \n\t"
"mfc1 %[tmp1], %[ftmp10] \n\t"
"addiu %[tmp1], %[tmp1], 0x04 \n\t"
"srl %[tmp1], %[tmp1], 0x03 \n\t"
"mul %[dc], %[tmp1], %[ff_pb_1] \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[ftmp10]"=&f"(ftmp[10]),
[tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
RESTRICT_ASM_ALL64
[dc]"=r"(dc)
: [srcA]"r"((mips_reg)(src-stride-1)),
[src0]"r"((mips_reg)(src-stride)),
[src1]"r"((mips_reg)(src-stride+1)),
[has_topleft]"r"(has_topleft), [has_topright]"r"(has_topright),
[ff_pb_1]"r"(ff_pb_1), [ff_pw_2]"f"(ff_pw_2)
: "memory"
);
__asm__ volatile (
"dli %[tmp0], 0x02 \n\t"
"punpcklwd %[ftmp0], %[dc], %[dc] \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDXC1(%[ftmp0], %[src], %[stride], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDXC1(%[ftmp0], %[src], %[stride], 0x00)
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[src]"+&r"(src)
: [dc]"f"(dc), [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred8x8l_dc_8_mmi(uint8_t *src, int has_topleft, int has_topright,
ptrdiff_t stride)
{
uint32_t dc, dc1, dc2;
double ftmp[14];
mips_reg tmp[1];
const int l0 = ((has_topleft ? src[-1+-1*stride] : src[-1+0*stride]) + 2*src[-1+0*stride] + src[-1+1*stride] + 2) >> 2;
const int l1 = (src[-1+0*stride] + 2*src[-1+1*stride] + src[-1+2*stride] + 2) >> 2;
const int l2 = (src[-1+1*stride] + 2*src[-1+2*stride] + src[-1+3*stride] + 2) >> 2;
const int l3 = (src[-1+2*stride] + 2*src[-1+3*stride] + src[-1+4*stride] + 2) >> 2;
const int l4 = (src[-1+3*stride] + 2*src[-1+4*stride] + src[-1+5*stride] + 2) >> 2;
const int l5 = (src[-1+4*stride] + 2*src[-1+5*stride] + src[-1+6*stride] + 2) >> 2;
const int l6 = (src[-1+5*stride] + 2*src[-1+6*stride] + src[-1+7*stride] + 2) >> 2;
const int l7 = (src[-1+6*stride] + 2*src[-1+7*stride] + src[-1+7*stride] + 2) >> 2;
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
__asm__ volatile (
MMI_ULDC1(%[ftmp4], %[srcA], 0x00)
MMI_ULDC1(%[ftmp5], %[src0], 0x00)
MMI_ULDC1(%[ftmp6], %[src1], 0x00)
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dli %[tmp0], 0x03 \n\t"
"punpcklbh %[ftmp7], %[ftmp4], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"punpcklbh %[ftmp9], %[ftmp5], %[ftmp0] \n\t"
"punpckhbh %[ftmp10], %[ftmp5], %[ftmp0] \n\t"
"punpcklbh %[ftmp11], %[ftmp6], %[ftmp0] \n\t"
"punpckhbh %[ftmp12], %[ftmp6], %[ftmp0] \n\t"
"pshufh %[ftmp3], %[ftmp8], %[ftmp1] \n\t"
"pshufh %[ftmp13], %[ftmp12], %[ftmp1] \n\t"
"pinsrh_3 %[ftmp8], %[ftmp8], %[ftmp13] \n\t"
"pinsrh_3 %[ftmp12], %[ftmp12], %[ftmp3] \n\t"
"bnez %[has_topleft], 1f \n\t"
"pinsrh_0 %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
"1: \n\t"
"bnez %[has_topright], 2f \n\t"
"pshufh %[ftmp13], %[ftmp10], %[ftmp1] \n\t"
"pinsrh_3 %[ftmp8], %[ftmp8], %[ftmp13] \n\t"
"2: \n\t"
"dli %[tmp0], 0x02 \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"pshufh %[ftmp2], %[ftmp1], %[ftmp0] \n\t"
"pmullh %[ftmp9], %[ftmp9], %[ftmp2] \n\t"
"pmullh %[ftmp10], %[ftmp10], %[ftmp2] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
"paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp11] \n\t"
"paddh %[ftmp8], %[ftmp8], %[ftmp12] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp2] \n\t"
"paddh %[ftmp8], %[ftmp8], %[ftmp2] \n\t"
"psrah %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"psrah %[ftmp8], %[ftmp8], %[ftmp1] \n\t"
"packushb %[ftmp5], %[ftmp7], %[ftmp8] \n\t"
"biadd %[ftmp4], %[ftmp5] \n\t"
"mfc1 %[dc2], %[ftmp4] \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]),
[ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[dc2]"=r"(dc2)
: [srcA]"r"((mips_reg)(src-stride-1)),
[src0]"r"((mips_reg)(src-stride)),
[src1]"r"((mips_reg)(src-stride+1)),
[has_topleft]"r"(has_topleft), [has_topright]"r"(has_topright)
: "memory"
);
dc1 = l0+l1+l2+l3+l4+l5+l6+l7;
dc = ((dc1+dc2+8)>>4)*0x01010101U;
__asm__ volatile (
"dli %[tmp0], 0x02 \n\t"
"punpcklwd %[ftmp0], %[dc], %[dc] \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDXC1(%[ftmp0], %[src], %[stride], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
MMI_SDXC1(%[ftmp0], %[src], %[stride], 0x00)
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[src]"+&r"(src)
: [dc]"f"(dc), [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred8x8l_vertical_8_mmi(uint8_t *src, int has_topleft,
int has_topright, ptrdiff_t stride)
{
double ftmp[12];
mips_reg tmp[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp3], %[srcA], 0x00)
MMI_LDC1(%[ftmp4], %[src0], 0x00)
MMI_LDC1(%[ftmp5], %[src1], 0x00)
"punpcklbh %[ftmp6], %[ftmp3], %[ftmp0] \n\t"
"punpckhbh %[ftmp7], %[ftmp3], %[ftmp0] \n\t"
"punpcklbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
"punpckhbh %[ftmp9], %[ftmp4], %[ftmp0] \n\t"
"punpcklbh %[ftmp10], %[ftmp5], %[ftmp0] \n\t"
"punpckhbh %[ftmp11], %[ftmp5], %[ftmp0] \n\t"
"bnez %[has_topleft], 1f \n\t"
"pinsrh_0 %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"1: \n\t"
"bnez %[has_topright], 2f \n\t"
"pinsrh_3 %[ftmp11], %[ftmp11], %[ftmp9] \n\t"
"2: \n\t"
"dli %[tmp0], 0x02 \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"pshufh %[ftmp2], %[ftmp1], %[ftmp0] \n\t"
"pmullh %[ftmp8], %[ftmp8], %[ftmp2] \n\t"
"pmullh %[ftmp9], %[ftmp9], %[ftmp2] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp11] \n\t"
"paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
"paddh %[ftmp7], %[ftmp7], %[ftmp2] \n\t"
"psrah %[ftmp6], %[ftmp6], %[ftmp1] \n\t"
"psrah %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"packushb %[ftmp4], %[ftmp6], %[ftmp7] \n\t"
MMI_SDC1(%[ftmp4], %[src], 0x00)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[src]"=r"(src)
: [srcA]"r"((mips_reg)(src-stride-1)),
[src0]"r"((mips_reg)(src-stride)),
[src1]"r"((mips_reg)(src-stride+1)),
[has_topleft]"r"(has_topleft), [has_topright]"r"(has_topright)
: "memory"
);
__asm__ volatile (
"dli %[tmp0], 0x02 \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[src]"+&r"(src)
: [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred4x4_dc_8_mmi(uint8_t *src, const uint8_t *topright,
ptrdiff_t stride)
{
const int dc = (src[-stride] + src[1-stride] + src[2-stride]
+ src[3-stride] + src[-1+0*stride] + src[-1+1*stride]
+ src[-1+2*stride] + src[-1+3*stride] + 4) >>3;
uint64_t tmp[2];
mips_reg addr[1];
DECLARE_VAR_ADDRT;
__asm__ volatile (
PTR_ADDU "%[tmp0], %[dc], $0 \n\t"
"dmul %[tmp1], %[tmp0], %[ff_pb_1] \n\t"
"xor %[addr0], %[addr0], %[addr0] \n\t"
MMI_SWX(%[tmp1], %[src], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SWX(%[tmp1], %[src], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SWX(%[tmp1], %[src], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SWX(%[tmp1], %[src], %[addr0], 0x00)
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
RESTRICT_ASM_ADDRT
[addr0]"=&r"(addr[0])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride),
[dc]"r"(dc), [ff_pb_1]"r"(ff_pb_1)
: "memory"
);
}
void ff_pred8x8_vertical_8_mmi(uint8_t *src, ptrdiff_t stride)
{
uint64_t tmp[2];
mips_reg addr[2];
__asm__ volatile (
PTR_SUBU "%[addr0], %[src], %[stride] \n\t"
PTR_ADDU "%[addr1], %[src], $0 \n\t"
"ldl %[tmp0], 0x07(%[addr0]) \n\t"
"ldr %[tmp0], 0x00(%[addr0]) \n\t"
"dli %[tmp1], 0x04 \n\t"
"1: \n\t"
"sdl %[tmp0], 0x07(%[addr1]) \n\t"
"sdr %[tmp0], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr1], %[stride] \n\t"
"sdl %[tmp0], 0x07(%[addr1]) \n\t"
"sdr %[tmp0], 0x00(%[addr1]) \n\t"
"daddi %[tmp1], -0x01 \n\t"
PTR_ADDU "%[addr1], %[stride] \n\t"
"bnez %[tmp1], 1b \n\t"
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred8x8_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride)
{
uint64_t tmp[3];
mips_reg addr[2];
__asm__ volatile (
PTR_ADDI "%[addr0], %[src], -0x01 \n\t"
PTR_ADDU "%[addr1], %[src], $0 \n\t"
"dli %[tmp0], 0x04 \n\t"
"1: \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"dmul %[tmp2], %[tmp1], %[ff_pb_1] \n\t"
"swl %[tmp2], 0x07(%[addr1]) \n\t"
"swr %[tmp2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"dmul %[tmp2], %[tmp1], %[ff_pb_1] \n\t"
"swl %[tmp2], 0x07(%[addr1]) \n\t"
"swr %[tmp2], 0x00(%[addr1]) \n\t"
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[tmp2]"=&r"(tmp[2]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride),
[ff_pb_1]"r"(ff_pb_1)
: "memory"
);
}
void ff_pred8x8_top_dc_8_mmi(uint8_t *src, ptrdiff_t stride)
{
double ftmp[4];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
"dli %[tmp0], 0x02 \n\t"
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
PTR_SUBU "%[addr0], %[src], %[stride] \n\t"
MMI_LDC1(%[ftmp1], %[addr0], 0x00)
"punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"biadd %[ftmp2], %[ftmp2] \n\t"
"biadd %[ftmp3], %[ftmp3] \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"pshufh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"pshufh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"pshufh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"paddush %[ftmp2], %[ftmp2], %[ftmp1] \n\t"
"paddush %[ftmp3], %[ftmp3], %[ftmp1] \n\t"
"mtc1 %[tmp0], %[ftmp1] \n\t"
"psrlh %[ftmp2], %[ftmp2], %[ftmp1] \n\t"
"psrlh %[ftmp3], %[ftmp3], %[ftmp1] \n\t"
"packushb %[ftmp1], %[ftmp2], %[ftmp3] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[src], 0x00)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[addr0]"=&r"(addr[0]),
[src]"+&r"(src)
: [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred8x8_dc_8_mmi(uint8_t *src, ptrdiff_t stride)
{
double ftmp[5];
mips_reg addr[7];
__asm__ volatile (
"negu %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[src] \n\t"
PTR_ADDIU "%[addr1], %[addr0], 0x04 \n\t"
"lbu %[addr2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr3], $0, %[addr2] \n\t"
PTR_ADDIU "%[addr0], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr4], $0, %[addr2] \n\t"
PTR_ADDIU "%[addr1], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr3], %[addr3], %[addr2] \n\t"
PTR_ADDIU "%[addr0], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr4], %[addr4], %[addr2] \n\t"
PTR_ADDIU "%[addr1], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr3], %[addr3], %[addr2] \n\t"
PTR_ADDIU "%[addr0], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr4], %[addr4], %[addr2] \n\t"
PTR_ADDIU "%[addr1], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr3], %[addr3], %[addr2] \n\t"
PTR_ADDIU "%[addr0], 0x01 \n\t"
"lbu %[addr2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr4], %[addr4], %[addr2] \n\t"
PTR_ADDIU "%[addr1], 0x01 \n\t"
"dli %[addr2], -0x01 \n\t"
PTR_ADDU "%[addr2], %[addr2], %[src] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr5], $0, %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr5], %[addr5], %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr5], %[addr5], %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr5], %[addr5], %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr6], $0, %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr6], %[addr6], %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr6], %[addr6], %[addr1] \n\t"
PTR_ADDU "%[addr2], %[addr2], %[stride] \n\t"
"lbu %[addr1], 0x00(%[addr2]) \n\t"
PTR_ADDU "%[addr6], %[addr6], %[addr1] \n\t"
PTR_ADDU "%[addr3], %[addr3], %[addr5] \n\t"
PTR_ADDIU "%[addr3], %[addr3], 0x04 \n\t"
PTR_ADDIU "%[addr4], %[addr4], 0x02 \n\t"
PTR_ADDIU "%[addr1], %[addr6], 0x02 \n\t"
PTR_ADDU "%[addr2], %[addr4], %[addr1] \n\t"
PTR_SRL "%[addr3], 0x03 \n\t"
PTR_SRL "%[addr4], 0x02 \n\t"
PTR_SRL "%[addr1], 0x02 \n\t"
PTR_SRL "%[addr2], 0x03 \n\t"
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dmtc1 %[addr3], %[ftmp1] \n\t"
"pshufh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"dmtc1 %[addr4], %[ftmp2] \n\t"
"pshufh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"dmtc1 %[addr1], %[ftmp3] \n\t"
"pshufh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"dmtc1 %[addr2], %[ftmp4] \n\t"
"pshufh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"packushb %[ftmp2], %[ftmp3], %[ftmp4] \n\t"
PTR_ADDU "%[addr0], $0, %[src] \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[addr0], 0x00)
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
MMI_SDC1(%[ftmp2], %[addr0], 0x00)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]),
[addr2]"=&r"(addr[2]), [addr3]"=&r"(addr[3]),
[addr4]"=&r"(addr[4]), [addr5]"=&r"(addr[5]),
[addr6]"=&r"(addr[6])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride)
: "memory"
);
}
void ff_pred8x16_vertical_8_mmi(uint8_t *src, ptrdiff_t stride)
{
double ftmp[1];
uint64_t tmp[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
MMI_LDC1(%[ftmp0], %[srcA], 0x00)
"dli %[tmp0], 0x04 \n\t"
"1: \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
PTR_ADDU "%[src], %[src], %[stride] \n\t"
MMI_SDC1(%[ftmp0], %[src], 0x00)
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[src], %[src], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[src]"+&r"(src)
: [stride]"r"((mips_reg)stride), [srcA]"r"((mips_reg)(src-stride))
: "memory"
);
}
void ff_pred8x16_horizontal_8_mmi(uint8_t *src, ptrdiff_t stride)
{
uint64_t tmp[3];
mips_reg addr[2];
__asm__ volatile (
PTR_ADDI "%[addr0], %[src], -0x01 \n\t"
PTR_ADDU "%[addr1], %[src], $0 \n\t"
"dli %[tmp0], 0x08 \n\t"
"1: \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"dmul %[tmp2], %[tmp1], %[ff_pb_1] \n\t"
"swl %[tmp2], 0x07(%[addr1]) \n\t"
"swr %[tmp2], 0x00(%[addr1]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"lbu %[tmp1], 0x00(%[addr0]) \n\t"
"dmul %[tmp2], %[tmp1], %[ff_pb_1] \n\t"
"swl %[tmp2], 0x07(%[addr1]) \n\t"
"swr %[tmp2], 0x00(%[addr1]) \n\t"
"daddi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr1], %[addr1], %[stride] \n\t"
"bnez %[tmp0], 1b \n\t"
: [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[tmp2]"=&r"(tmp[2]),
[addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1])
: [src]"r"((mips_reg)src), [stride]"r"((mips_reg)stride),
[ff_pb_1]"r"(ff_pb_1)
: "memory"
);
}
static inline void pred16x16_plane_compat_mmi(uint8_t *src, int stride,
const int svq3, const int rv40)
{
double ftmp[11];
uint64_t tmp[6];
mips_reg addr[1];
DECLARE_VAR_ALL64;
__asm__ volatile(
PTR_SUBU "%[addr0], %[src], %[stride] \n\t"
"dli %[tmp0], 0x20 \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
MMI_ULDC1(%[ftmp0], %[addr0], -0x01)
MMI_ULDC1(%[ftmp2], %[addr0], 0x08)
"dsrl %[ftmp1], %[ftmp0], %[ftmp4] \n\t"
"dsrl %[ftmp3], %[ftmp2], %[ftmp4] \n\t"
"xor %[ftmp4], %[ftmp4], %[ftmp4] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp4] \n\t"
"punpcklbh %[ftmp1], %[ftmp1], %[ftmp4] \n\t"
"punpcklbh %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"punpcklbh %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"pmullh %[ftmp0], %[ftmp0], %[ff_pw_m8tom5] \n\t"
"pmullh %[ftmp1], %[ftmp1], %[ff_pw_m4tom1] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ff_pw_1to4] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[ff_pw_5to8] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp2] \n\t"
"paddsh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"dli %[tmp0], 0x0e \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"pshufh %[ftmp1], %[ftmp0], %[ftmp4] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"dli %[tmp0], 0x01 \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"pshufh %[ftmp1], %[ftmp0], %[ftmp4] \n\t"
"paddsh %[ftmp5], %[ftmp0], %[ftmp1] \n\t"
PTR_ADDIU "%[addr0], %[src], -0x01 \n\t"
PTR_SUBU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp2], 0x00(%[addr0]) \n\t"
"lbu %[tmp5], 0x10(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp3], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp4], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"dsll %[tmp3], %[tmp3], 0x10 \n\t"
"dsll %[tmp4], %[tmp4], 0x20 \n\t"
"dsll %[tmp0], %[tmp0], 0x30 \n\t"
"or %[tmp4], %[tmp4], %[tmp0] \n\t"
"or %[tmp2], %[tmp2], %[tmp3] \n\t"
"or %[tmp2], %[tmp2], %[tmp4] \n\t"
"dmtc1 %[tmp2], %[ftmp0] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp3], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp4], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"dsll %[tmp3], %[tmp3], 0x10 \n\t"
"dsll %[tmp4], %[tmp4], 0x20 \n\t"
"dsll %[tmp0], %[tmp0], 0x30 \n\t"
"or %[tmp4], %[tmp4], %[tmp0] \n\t"
"or %[tmp2], %[tmp2], %[tmp3] \n\t"
"or %[tmp2], %[tmp2], %[tmp4] \n\t"
"dmtc1 %[tmp2], %[ftmp1] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp3], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp4], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"dsll %[tmp3], %[tmp3], 0x10 \n\t"
"dsll %[tmp4], %[tmp4], 0x20 \n\t"
"dsll %[tmp0], %[tmp0], 0x30 \n\t"
"or %[tmp4], %[tmp4], %[tmp0] \n\t"
"or %[tmp2], %[tmp2], %[tmp3] \n\t"
"or %[tmp2], %[tmp2], %[tmp4] \n\t"
"dmtc1 %[tmp2], %[ftmp2] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp2], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp3], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp4], 0x00(%[addr0]) \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"lbu %[tmp0], 0x00(%[addr0]) \n\t"
"daddu %[tmp5], %[tmp5], %[tmp0] \n\t"
"daddiu %[tmp5], %[tmp5], 0x01 \n\t"
"dsll %[tmp5], %[tmp5], 0x04 \n\t"
"dsll %[tmp3], %[tmp3], 0x10 \n\t"
"dsll %[tmp4], %[tmp4], 0x20 \n\t"
"dsll %[tmp0], %[tmp0], 0x30 \n\t"
"or %[tmp4], %[tmp4], %[tmp0] \n\t"
"or %[tmp2], %[tmp2], %[tmp3] \n\t"
"or %[tmp2], %[tmp2], %[tmp4] \n\t"
"dmtc1 %[tmp2], %[ftmp3] \n\t"
"pmullh %[ftmp0], %[ftmp0], %[ff_pw_m8tom5] \n\t"
"pmullh %[ftmp1], %[ftmp1], %[ff_pw_m4tom1] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ff_pw_1to4] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[ff_pw_5to8] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp2] \n\t"
"paddsh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"dli %[tmp0], 0x0e \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"pshufh %[ftmp1], %[ftmp0], %[ftmp4] \n\t"
"paddsh %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"dli %[tmp0], 0x01 \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"pshufh %[ftmp1], %[ftmp0], %[ftmp4] \n\t"
"paddsh %[ftmp6], %[ftmp0], %[ftmp1] \n\t"
"dmfc1 %[tmp0], %[ftmp5] \n\t"
"dsll %[tmp0], %[tmp0], 0x30 \n\t"
"dsra %[tmp0], %[tmp0], 0x30 \n\t"
"dmfc1 %[tmp1], %[ftmp6] \n\t"
"dsll %[tmp1], %[tmp1], 0x30 \n\t"
"dsra %[tmp1], %[tmp1], 0x30 \n\t"
"beqz %[svq3], 1f \n\t"
"dli %[tmp2], 0x04 \n\t"
"ddiv %[tmp0], %[tmp0], %[tmp2] \n\t"
"ddiv %[tmp1], %[tmp1], %[tmp2] \n\t"
"dli %[tmp2], 0x05 \n\t"
"dmul %[tmp0], %[tmp0], %[tmp2] \n\t"
"dmul %[tmp1], %[tmp1], %[tmp2] \n\t"
"dli %[tmp2], 0x10 \n\t"
"ddiv %[tmp0], %[tmp0], %[tmp2] \n\t"
"ddiv %[tmp1], %[tmp1], %[tmp2] \n\t"
"daddu %[tmp2], %[tmp0], $0 \n\t"
"daddu %[tmp0], %[tmp1], $0 \n\t"
"daddu %[tmp1], %[tmp2], $0 \n\t"
"b 2f \n\t"
"1: \n\t"
"beqz %[rv40], 1f \n\t"
"dsra %[tmp2], %[tmp0], 0x02 \n\t"
"daddu %[tmp0], %[tmp0], %[tmp2] \n\t"
"dsra %[tmp2], %[tmp1], 0x02 \n\t"
"daddu %[tmp1], %[tmp1], %[tmp2] \n\t"
"dsra %[tmp0], %[tmp0], 0x04 \n\t"
"dsra %[tmp1], %[tmp1], 0x04 \n\t"
"b 2f \n\t"
"1: \n\t"
"dli %[tmp2], 0x05 \n\t"
"dmul %[tmp0], %[tmp0], %[tmp2] \n\t"
"dmul %[tmp1], %[tmp1], %[tmp2] \n\t"
"daddiu %[tmp0], %[tmp0], 0x20 \n\t"
"daddiu %[tmp1], %[tmp1], 0x20 \n\t"
"dsra %[tmp0], %[tmp0], 0x06 \n\t"
"dsra %[tmp1], %[tmp1], 0x06 \n\t"
"2: \n\t"
"daddu %[tmp3], %[tmp0], %[tmp1] \n\t"
"dli %[tmp2], 0x07 \n\t"
"dmul %[tmp3], %[tmp3], %[tmp2] \n\t"
"dsubu %[tmp5], %[tmp5], %[tmp3] \n\t"
"xor %[ftmp4], %[ftmp4], %[ftmp4] \n\t"
"dmtc1 %[tmp0], %[ftmp0] \n\t"
"pshufh %[ftmp0], %[ftmp0], %[ftmp4] \n\t"
"dmtc1 %[tmp1], %[ftmp5] \n\t"
"pshufh %[ftmp5], %[ftmp5], %[ftmp4] \n\t"
"dmtc1 %[tmp5], %[ftmp6] \n\t"
"pshufh %[ftmp6], %[ftmp6], %[ftmp4] \n\t"
"dli %[tmp0], 0x05 \n\t"
"dmtc1 %[tmp0], %[ftmp7] \n\t"
"pmullh %[ftmp1], %[ff_pw_0to3], %[ftmp0] \n\t"
"dmtc1 %[ff_pw_4to7], %[ftmp2] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"dmtc1 %[ff_pw_8tob], %[ftmp3] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"dmtc1 %[ff_pw_ctof], %[ftmp4] \n\t"
"pmullh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
"dli %[tmp0], 0x10 \n\t"
PTR_ADDU "%[addr0], %[src], $0 \n\t"
"1: \n\t"
"paddsh %[ftmp8], %[ftmp1], %[ftmp6] \n\t"
"psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t"
"paddsh %[ftmp9], %[ftmp2], %[ftmp6] \n\t"
"psrah %[ftmp9], %[ftmp9], %[ftmp7] \n\t"
"packushb %[ftmp0], %[ftmp8], %[ftmp9] \n\t"
MMI_SDC1(%[ftmp0], %[addr0], 0x00)
"paddsh %[ftmp8], %[ftmp3], %[ftmp6] \n\t"
"psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t"
"paddsh %[ftmp9], %[ftmp4], %[ftmp6] \n\t"
"psrah %[ftmp9], %[ftmp9], %[ftmp7] \n\t"
"packushb %[ftmp0], %[ftmp8], %[ftmp9] \n\t"
MMI_SDC1(%[ftmp0], %[addr0], 0x08)
"paddsh %[ftmp6], %[ftmp6], %[ftmp5] \n\t"
PTR_ADDU "%[addr0], %[addr0], %[stride] \n\t"
"daddiu %[tmp0], %[tmp0], -0x01 \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[tmp2]"=&r"(tmp[2]), [tmp3]"=&r"(tmp[3]),
[tmp4]"=&r"(tmp[4]), [tmp5]"=&r"(tmp[5]),
RESTRICT_ASM_ALL64
[addr0]"=&r"(addr[0])
: [src]"r"(src), [stride]"r"((mips_reg)stride),
[svq3]"r"(svq3), [rv40]"r"(rv40),
[ff_pw_m8tom5]"f"(ff_pw_m8tom5), [ff_pw_m4tom1]"f"(ff_pw_m4tom1),
[ff_pw_1to4]"f"(ff_pw_1to4), [ff_pw_5to8]"f"(ff_pw_5to8),
[ff_pw_0to3]"f"(ff_pw_0to3), [ff_pw_4to7]"r"(ff_pw_4to7),
[ff_pw_8tob]"r"(ff_pw_8tob), [ff_pw_ctof]"r"(ff_pw_ctof)
: "memory"
);
}
void ff_pred16x16_plane_h264_8_mmi(uint8_t *src, ptrdiff_t stride)
{
pred16x16_plane_compat_mmi(src, stride, 0, 0);
}
void ff_pred16x16_plane_svq3_8_mmi(uint8_t *src, ptrdiff_t stride)
{
pred16x16_plane_compat_mmi(src, stride, 1, 0);
}
void ff_pred16x16_plane_rv40_8_mmi(uint8_t *src, ptrdiff_t stride)
{
pred16x16_plane_compat_mmi(src, stride, 0, 1);
}

View File

@@ -0,0 +1,690 @@
/*
* Copyright (c) 2015 - 2017 Shivraj Patil (Shivraj.Patil@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "h264dsp_mips.h"
static void intra_predict_vert_8x8_msa(uint8_t *src, uint8_t *dst,
int32_t dst_stride)
{
uint64_t out = LD(src);
SD4(out, out, out, out, dst, dst_stride);
dst += (4 * dst_stride);
SD4(out, out, out, out, dst, dst_stride);
}
static void intra_predict_vert_16x16_msa(uint8_t *src, uint8_t *dst,
int32_t dst_stride)
{
v16u8 out = LD_UB(src);
ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride);
dst += (8 * dst_stride);
ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride);
}
static void intra_predict_horiz_8x8_msa(uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride)
{
uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
out0 = src[0 * src_stride] * 0x0101010101010101;
out1 = src[1 * src_stride] * 0x0101010101010101;
out2 = src[2 * src_stride] * 0x0101010101010101;
out3 = src[3 * src_stride] * 0x0101010101010101;
out4 = src[4 * src_stride] * 0x0101010101010101;
out5 = src[5 * src_stride] * 0x0101010101010101;
out6 = src[6 * src_stride] * 0x0101010101010101;
out7 = src[7 * src_stride] * 0x0101010101010101;
SD4(out0, out1, out2, out3, dst, dst_stride);
dst += (4 * dst_stride);
SD4(out4, out5, out6, out7, dst, dst_stride);
}
static void intra_predict_horiz_16x16_msa(uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride)
{
uint8_t inp0, inp1, inp2, inp3;
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
v16u8 src8, src9, src10, src11, src12, src13, src14, src15;
inp0 = src[0 * src_stride];
inp1 = src[1 * src_stride];
inp2 = src[2 * src_stride];
inp3 = src[3 * src_stride];
src0 = (v16u8) __msa_fill_b(inp0);
src1 = (v16u8) __msa_fill_b(inp1);
src2 = (v16u8) __msa_fill_b(inp2);
src3 = (v16u8) __msa_fill_b(inp3);
inp0 = src[4 * src_stride];
inp1 = src[5 * src_stride];
inp2 = src[6 * src_stride];
inp3 = src[7 * src_stride];
src4 = (v16u8) __msa_fill_b(inp0);
src5 = (v16u8) __msa_fill_b(inp1);
src6 = (v16u8) __msa_fill_b(inp2);
src7 = (v16u8) __msa_fill_b(inp3);
inp0 = src[ 8 * src_stride];
inp1 = src[ 9 * src_stride];
inp2 = src[10 * src_stride];
inp3 = src[11 * src_stride];
src8 = (v16u8) __msa_fill_b(inp0);
src9 = (v16u8) __msa_fill_b(inp1);
src10 = (v16u8) __msa_fill_b(inp2);
src11 = (v16u8) __msa_fill_b(inp3);
inp0 = src[12 * src_stride];
inp1 = src[13 * src_stride];
inp2 = src[14 * src_stride];
inp3 = src[15 * src_stride];
src12 = (v16u8) __msa_fill_b(inp0);
src13 = (v16u8) __msa_fill_b(inp1);
src14 = (v16u8) __msa_fill_b(inp2);
src15 = (v16u8) __msa_fill_b(inp3);
ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride);
dst += (8 * dst_stride);
ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15,
dst, dst_stride);
}
#define INTRA_PREDICT_VALDC_8X8_MSA(val) \
static void intra_predict_##val##dc_8x8_msa(uint8_t *dst, int32_t dst_stride) \
{ \
v16i8 store = __msa_fill_b(val); \
uint64_t out = __msa_copy_u_d((v2i64) store, 0); \
\
SD4(out, out, out, out, dst, dst_stride); \
dst += (4 * dst_stride); \
SD4(out, out, out, out, dst, dst_stride); \
}
INTRA_PREDICT_VALDC_8X8_MSA(127);
INTRA_PREDICT_VALDC_8X8_MSA(129);
#define INTRA_PREDICT_VALDC_16X16_MSA(val) \
static void intra_predict_##val##dc_16x16_msa(uint8_t *dst, \
int32_t dst_stride) \
{ \
v16u8 out = (v16u8) __msa_fill_b(val); \
\
ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); \
dst += (8 * dst_stride); \
ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); \
}
INTRA_PREDICT_VALDC_16X16_MSA(127);
INTRA_PREDICT_VALDC_16X16_MSA(129);
static void intra_predict_plane_8x8_msa(uint8_t *src, int32_t stride)
{
uint8_t lpcnt;
int32_t res, res0, res1, res2, res3;
uint64_t out0, out1;
v16i8 shf_mask = { 3, 5, 2, 6, 1, 7, 0, 8, 3, 5, 2, 6, 1, 7, 0, 8 };
v8i16 short_multiplier = { 1, 2, 3, 4, 1, 2, 3, 4 };
v4i32 int_multiplier = { 0, 1, 2, 3 };
v16u8 src_top;
v8i16 vec9, vec10, vec11;
v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8;
v2i64 sum;
src_top = LD_UB(src - (stride + 1));
src_top = (v16u8) __msa_vshf_b(shf_mask, (v16i8) src_top, (v16i8) src_top);
vec9 = __msa_hsub_u_h(src_top, src_top);
vec9 *= short_multiplier;
vec8 = __msa_hadd_s_w(vec9, vec9);
sum = __msa_hadd_s_d(vec8, vec8);
res0 = __msa_copy_s_w((v4i32) sum, 0);
res1 = (src[4 * stride - 1] - src[2 * stride - 1]) +
2 * (src[5 * stride - 1] - src[stride - 1]) +
3 * (src[6 * stride - 1] - src[-1]) +
4 * (src[7 * stride - 1] - src[-stride - 1]);
res0 *= 17;
res1 *= 17;
res0 = (res0 + 16) >> 5;
res1 = (res1 + 16) >> 5;
res3 = 3 * (res0 + res1);
res2 = 16 * (src[7 * stride - 1] + src[-stride + 7] + 1);
res = res2 - res3;
vec8 = __msa_fill_w(res0);
vec4 = __msa_fill_w(res);
vec2 = __msa_fill_w(res1);
vec5 = vec8 * int_multiplier;
vec3 = vec8 * 4;
for (lpcnt = 4; lpcnt--;) {
vec0 = vec5;
vec0 += vec4;
vec1 = vec0 + vec3;
vec6 = vec5;
vec4 += vec2;
vec6 += vec4;
vec7 = vec6 + vec3;
SRA_4V(vec0, vec1, vec6, vec7, 5);
PCKEV_H2_SH(vec1, vec0, vec7, vec6, vec10, vec11);
CLIP_SH2_0_255(vec10, vec11);
PCKEV_B2_SH(vec10, vec10, vec11, vec11, vec10, vec11);
out0 = __msa_copy_s_d((v2i64) vec10, 0);
out1 = __msa_copy_s_d((v2i64) vec11, 0);
SD(out0, src);
src += stride;
SD(out1, src);
src += stride;
vec4 += vec2;
}
}
static void intra_predict_plane_16x16_msa(uint8_t *src, int32_t stride)
{
uint8_t lpcnt;
int32_t res0, res1, res2, res3;
uint64_t load0, load1;
v16i8 shf_mask = { 7, 8, 6, 9, 5, 10, 4, 11, 3, 12, 2, 13, 1, 14, 0, 15 };
v8i16 short_multiplier = { 1, 2, 3, 4, 5, 6, 7, 8 };
v4i32 int_multiplier = { 0, 1, 2, 3 };
v16u8 src_top = { 0 };
v16u8 store0, store1;
v8i16 vec9, vec10, vec11, vec12;
v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, res_add;
v4i32 reg0, reg1, reg2, reg3;
load0 = LD(src - (stride + 1));
load1 = LD(src - (stride + 1) + 9);
INSERT_D2_UB(load0, load1, src_top);
src_top = (v16u8) __msa_vshf_b(shf_mask, (v16i8) src_top, (v16i8) src_top);
vec9 = __msa_hsub_u_h(src_top, src_top);
vec9 *= short_multiplier;
vec8 = __msa_hadd_s_w(vec9, vec9);
res_add = (v4i32) __msa_hadd_s_d(vec8, vec8);
res0 = __msa_copy_s_w(res_add, 0) + __msa_copy_s_w(res_add, 2);
res1 = (src[8 * stride - 1] - src[6 * stride - 1]) +
2 * (src[9 * stride - 1] - src[5 * stride - 1]) +
3 * (src[10 * stride - 1] - src[4 * stride - 1]) +
4 * (src[11 * stride - 1] - src[3 * stride - 1]) +
5 * (src[12 * stride - 1] - src[2 * stride - 1]) +
6 * (src[13 * stride - 1] - src[stride - 1]) +
7 * (src[14 * stride - 1] - src[-1]) +
8 * (src[15 * stride - 1] - src[-1 * stride - 1]);
res0 *= 5;
res1 *= 5;
res0 = (res0 + 32) >> 6;
res1 = (res1 + 32) >> 6;
res3 = 7 * (res0 + res1);
res2 = 16 * (src[15 * stride - 1] + src[-stride + 15] + 1);
res2 -= res3;
vec8 = __msa_fill_w(res0);
vec4 = __msa_fill_w(res2);
vec5 = __msa_fill_w(res1);
vec6 = vec8 * 4;
vec7 = vec8 * int_multiplier;
for (lpcnt = 8; lpcnt--;) {
vec0 = vec7;
reg0 = vec7;
vec0 += vec4;
vec4 += vec5;
reg0 += vec4;
vec1 = vec0 + vec6;
reg1 = reg0 + vec6;
vec2 = vec1 + vec6;
reg2 = reg1 + vec6;
vec3 = vec2 + vec6;
reg3 = reg2 + vec6;
SRA_4V(vec0, vec1, vec2, vec3, 5);
SRA_4V(reg0, reg1, reg2, reg3, 5);
PCKEV_H2_SH(vec1, vec0, vec3, vec2, vec9, vec10);
PCKEV_H2_SH(reg1, reg0, reg3, reg2, vec11, vec12);
CLIP_SH2_0_255(vec9, vec10);
CLIP_SH2_0_255(vec11, vec12);
PCKEV_B2_UB(vec10, vec9, vec12, vec11, store0, store1);
ST_UB2(store0, store1, src, stride);
src += 2 * stride;
vec4 += vec5;
}
}
static void intra_predict_dc_4blk_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0, src1, src3, src2;
uint32_t out0, out1, out2, out3;
uint64_t store0, store1;
v16u8 src_top;
v8u16 add;
v4u32 sum;
src_top = LD_UB(src - stride);
add = __msa_hadd_u_h((v16u8) src_top, (v16u8) src_top);
sum = __msa_hadd_u_w(add, add);
src0 = __msa_copy_u_w((v4i32) sum, 0);
src1 = __msa_copy_u_w((v4i32) sum, 1);
src0 += src[0 * stride - 1];
src0 += src[1 * stride - 1];
src0 += src[2 * stride - 1];
src0 += src[3 * stride - 1];
src2 = src[4 * stride - 1];
src2 += src[5 * stride - 1];
src2 += src[6 * stride - 1];
src2 += src[7 * stride - 1];
src0 = (src0 + 4) >> 3;
src3 = (src1 + src2 + 4) >> 3;
src1 = (src1 + 2) >> 2;
src2 = (src2 + 2) >> 2;
out0 = src0 * 0x01010101;
out1 = src1 * 0x01010101;
out2 = src2 * 0x01010101;
out3 = src3 * 0x01010101;
store0 = ((uint64_t) out1 << 32) | out0;
store1 = ((uint64_t) out3 << 32) | out2;
SD4(store0, store0, store0, store0, src, stride);
src += (4 * stride);
SD4(store1, store1, store1, store1, src, stride);
}
static void intra_predict_hor_dc_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0, src1;
uint64_t out0, out1;
src0 = src[0 * stride - 1];
src0 += src[1 * stride - 1];
src0 += src[2 * stride - 1];
src0 += src[3 * stride - 1];
src1 = src[4 * stride - 1];
src1 += src[5 * stride - 1];
src1 += src[6 * stride - 1];
src1 += src[7 * stride - 1];
src0 = (src0 + 2) >> 2;
src1 = (src1 + 2) >> 2;
out0 = src0 * 0x0101010101010101;
out1 = src1 * 0x0101010101010101;
SD4(out0, out0, out0, out0, src, stride);
src += (4 * stride);
SD4(out1, out1, out1, out1, src, stride);
}
static void intra_predict_vert_dc_8x8_msa(uint8_t *src, int32_t stride)
{
uint64_t out0;
v16i8 mask = { 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };
v16u8 src_top, res0;
v8u16 add;
v4u32 sum;
src_top = LD_UB(src - stride);
add = __msa_hadd_u_h(src_top, src_top);
sum = __msa_hadd_u_w(add, add);
sum = (v4u32) __msa_srari_w((v4i32) sum, 2);
res0 = (v16u8) __msa_vshf_b(mask, (v16i8) sum, (v16i8) sum);
out0 = __msa_copy_u_d((v2i64) res0, 0);
SD4(out0, out0, out0, out0, src, stride);
src += (4 * stride);
SD4(out0, out0, out0, out0, src, stride);
}
static void intra_predict_mad_cow_dc_l0t_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0, src1, src2;
uint32_t out0, out1, out2;
uint64_t store0, store1;
v16u8 src_top;
v8u16 add;
v4u32 sum;
src_top = LD_UB(src - stride);
add = __msa_hadd_u_h(src_top, src_top);
sum = __msa_hadd_u_w(add, add);
src0 = __msa_copy_u_w((v4i32) sum, 0);
src1 = __msa_copy_u_w((v4i32) sum, 1);
src2 = src[0 * stride - 1];
src2 += src[1 * stride - 1];
src2 += src[2 * stride - 1];
src2 += src[3 * stride - 1];
src2 = (src0 + src2 + 4) >> 3;
src0 = (src0 + 2) >> 2;
src1 = (src1 + 2) >> 2;
out0 = src0 * 0x01010101;
out1 = src1 * 0x01010101;
out2 = src2 * 0x01010101;
store1 = ((uint64_t) out1 << 32);
store0 = store1 | ((uint64_t) out2);
store1 = store1 | ((uint64_t) out0);
SD4(store0, store0, store0, store0, src, stride);
src += (4 * stride);
SD4(store1, store1, store1, store1, src, stride);
}
static void intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0, src1, src2, src3;
uint32_t out0, out1, out2, out3;
uint64_t store0, store1;
v16u8 src_top;
v8u16 add;
v4u32 sum;
src_top = LD_UB(src - stride);
add = __msa_hadd_u_h(src_top, src_top);
sum = __msa_hadd_u_w(add, add);
src0 = __msa_copy_u_w((v4i32) sum, 0);
src1 = __msa_copy_u_w((v4i32) sum, 1);
src2 = src[4 * stride - 1];
src2 += src[5 * stride - 1];
src2 += src[6 * stride - 1];
src2 += src[7 * stride - 1];
src0 = (src0 + 2) >> 2;
src3 = (src1 + src2 + 4) >> 3;
src1 = (src1 + 2) >> 2;
src2 = (src2 + 2) >> 2;
out0 = src0 * 0x01010101;
out1 = src1 * 0x01010101;
out2 = src2 * 0x01010101;
out3 = src3 * 0x01010101;
store0 = ((uint64_t) out1 << 32) | out0;
store1 = ((uint64_t) out3 << 32) | out2;
SD4(store0, store0, store0, store0, src, stride);
src += (4 * stride);
SD4(store1, store1, store1, store1, src, stride);
}
static void intra_predict_mad_cow_dc_l00_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0;
uint64_t out0, out1;
src0 = src[0 * stride - 1];
src0 += src[1 * stride - 1];
src0 += src[2 * stride - 1];
src0 += src[3 * stride - 1];
src0 = (src0 + 2) >> 2;
out0 = src0 * 0x0101010101010101;
out1 = 0x8080808080808080;
SD4(out0, out0, out0, out0, src, stride);
src += (4 * stride);
SD4(out1, out1, out1, out1, src, stride);
}
static void intra_predict_mad_cow_dc_0l0_8x8_msa(uint8_t *src, int32_t stride)
{
uint32_t src0;
uint64_t out0, out1;
src0 = src[4 * stride - 1];
src0 += src[5 * stride - 1];
src0 += src[6 * stride - 1];
src0 += src[7 * stride - 1];
src0 = (src0 + 2) >> 2;
out0 = 0x8080808080808080;
out1 = src0 * 0x0101010101010101;
SD4(out0, out0, out0, out0, src, stride);
src += (4 * stride);
SD4(out1, out1, out1, out1, src, stride);
}
void ff_h264_intra_predict_plane_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_plane_8x8_msa(src, stride);
}
void ff_h264_intra_predict_dc_4blk_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_dc_4blk_8x8_msa(src, stride);
}
void ff_h264_intra_predict_hor_dc_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_hor_dc_8x8_msa(src, stride);
}
void ff_h264_intra_predict_vert_dc_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_vert_dc_8x8_msa(src, stride);
}
void ff_h264_intra_predict_mad_cow_dc_l0t_8x8_msa(uint8_t *src,
ptrdiff_t stride)
{
intra_predict_mad_cow_dc_l0t_8x8_msa(src, stride);
}
void ff_h264_intra_predict_mad_cow_dc_0lt_8x8_msa(uint8_t *src,
ptrdiff_t stride)
{
intra_predict_mad_cow_dc_0lt_8x8_msa(src, stride);
}
void ff_h264_intra_predict_mad_cow_dc_l00_8x8_msa(uint8_t *src,
ptrdiff_t stride)
{
intra_predict_mad_cow_dc_l00_8x8_msa(src, stride);
}
void ff_h264_intra_predict_mad_cow_dc_0l0_8x8_msa(uint8_t *src,
ptrdiff_t stride)
{
intra_predict_mad_cow_dc_0l0_8x8_msa(src, stride);
}
void ff_h264_intra_predict_plane_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_plane_16x16_msa(src, stride);
}
void ff_h264_intra_pred_vert_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *dst = src;
intra_predict_vert_8x8_msa(src - stride, dst, stride);
}
void ff_h264_intra_pred_horiz_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *dst = src;
intra_predict_horiz_8x8_msa(src - 1, stride, dst, stride);
}
void ff_h264_intra_pred_dc_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *src_top = src - stride;
uint8_t *src_left = src - 1;
uint8_t *dst = src;
uint32_t addition = 0;
v16u8 src_above, out;
v8u16 sum_above;
v4u32 sum_top;
v2u64 sum;
src_above = LD_UB(src_top);
sum_above = __msa_hadd_u_h(src_above, src_above);
sum_top = __msa_hadd_u_w(sum_above, sum_above);
sum = __msa_hadd_u_d(sum_top, sum_top);
sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum);
sum = __msa_hadd_u_d(sum_top, sum_top);
addition = __msa_copy_u_w((v4i32) sum, 0);
addition += src_left[ 0 * stride];
addition += src_left[ 1 * stride];
addition += src_left[ 2 * stride];
addition += src_left[ 3 * stride];
addition += src_left[ 4 * stride];
addition += src_left[ 5 * stride];
addition += src_left[ 6 * stride];
addition += src_left[ 7 * stride];
addition += src_left[ 8 * stride];
addition += src_left[ 9 * stride];
addition += src_left[10 * stride];
addition += src_left[11 * stride];
addition += src_left[12 * stride];
addition += src_left[13 * stride];
addition += src_left[14 * stride];
addition += src_left[15 * stride];
addition = (addition + 16) >> 5;
out = (v16u8) __msa_fill_b(addition);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
dst += (8 * stride);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
}
void ff_h264_intra_pred_vert_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *dst = src;
intra_predict_vert_16x16_msa(src - stride, dst, stride);
}
void ff_h264_intra_pred_horiz_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *dst = src;
intra_predict_horiz_16x16_msa(src - 1, stride, dst, stride);
}
void ff_h264_intra_pred_dc_left_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *src_left = src - 1;
uint8_t *dst = src;
uint32_t addition;
v16u8 out;
addition = src_left[ 0 * stride];
addition += src_left[ 1 * stride];
addition += src_left[ 2 * stride];
addition += src_left[ 3 * stride];
addition += src_left[ 4 * stride];
addition += src_left[ 5 * stride];
addition += src_left[ 6 * stride];
addition += src_left[ 7 * stride];
addition += src_left[ 8 * stride];
addition += src_left[ 9 * stride];
addition += src_left[10 * stride];
addition += src_left[11 * stride];
addition += src_left[12 * stride];
addition += src_left[13 * stride];
addition += src_left[14 * stride];
addition += src_left[15 * stride];
addition = (addition + 8) >> 4;
out = (v16u8) __msa_fill_b(addition);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
dst += (8 * stride);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
}
void ff_h264_intra_pred_dc_top_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
uint8_t *src_top = src - stride;
uint8_t *dst = src;
v16u8 src_above, out;
v8u16 sum_above;
v4u32 sum_top;
v2u64 sum;
src_above = LD_UB(src_top);
sum_above = __msa_hadd_u_h(src_above, src_above);
sum_top = __msa_hadd_u_w(sum_above, sum_above);
sum = __msa_hadd_u_d(sum_top, sum_top);
sum_top = (v4u32) __msa_pckev_w((v4i32) sum, (v4i32) sum);
sum = __msa_hadd_u_d(sum_top, sum_top);
sum = (v2u64) __msa_srari_d((v2i64) sum, 4);
out = (v16u8) __msa_splati_b((v16i8) sum, 0);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
dst += (8 * stride);
ST_UB8(out, out, out, out, out, out, out, out, dst, stride);
}
void ff_h264_intra_pred_dc_128_8x8_msa(uint8_t *src, ptrdiff_t stride)
{
uint64_t out;
v16u8 store;
store = (v16u8) __msa_fill_b(128);
out = __msa_copy_u_d((v2i64) store, 0);
SD4(out, out, out, out, src, stride);
src += (4 * stride);
SD4(out, out, out, out, src, stride);
}
void ff_h264_intra_pred_dc_128_16x16_msa(uint8_t *src, ptrdiff_t stride)
{
v16u8 out;
out = (v16u8) __msa_fill_b(128);
ST_UB8(out, out, out, out, out, out, out, out, src, stride);
src += (8 * stride);
ST_UB8(out, out, out, out, out, out, out, out, src, stride);
}
void ff_vp8_pred8x8_127_dc_8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_127dc_8x8_msa(src, stride);
}
void ff_vp8_pred8x8_129_dc_8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_129dc_8x8_msa(src, stride);
}
void ff_vp8_pred16x16_127_dc_8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_127dc_16x16_msa(src, stride);
}
void ff_vp8_pred16x16_129_dc_8_msa(uint8_t *src, ptrdiff_t stride)
{
intra_predict_129dc_16x16_msa(src, stride);
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264dsp_mips.h"
#if HAVE_MSA
static av_cold void h264qpel_init_msa(H264QpelContext *c, int bit_depth)
{
if (8 == bit_depth) {
c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_msa;
c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_msa;
c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_msa;
c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_msa;
c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_msa;
c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_msa;
c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_msa;
c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_msa;
c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_msa;
c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_msa;
c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_msa;
c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_msa;
c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_msa;
c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_msa;
c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_msa;
c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_msa;
c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_msa;
c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_msa;
c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_msa;
c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_msa;
c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_msa;
c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_msa;
c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_msa;
c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_msa;
c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_msa;
c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_msa;
c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_msa;
c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_msa;
c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_msa;
c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_msa;
c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_msa;
c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_msa;
c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_msa;
c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_msa;
c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_msa;
c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_msa;
c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_msa;
c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_msa;
c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_msa;
c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_msa;
c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_msa;
c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_msa;
c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_msa;
c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_msa;
c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_msa;
c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_msa;
c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_msa;
c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_msa;
c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_msa;
c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_msa;
c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_msa;
c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_msa;
c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_msa;
c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_msa;
c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_msa;
c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_msa;
c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_msa;
c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_msa;
c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_msa;
c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_msa;
c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_msa;
c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_msa;
c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_msa;
c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_msa;
c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_msa;
c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_msa;
c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_msa;
c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_msa;
c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_msa;
c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_msa;
c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_msa;
c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_msa;
c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_msa;
c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_msa;
c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_msa;
c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_msa;
c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_msa;
c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_msa;
c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_msa;
c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_msa;
c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_msa;
c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_msa;
c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_msa;
c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_msa;
c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_msa;
c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_msa;
c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_msa;
c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_msa;
c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_msa;
c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_msa;
c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_msa;
c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_msa;
c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_msa;
c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_msa;
c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_msa;
}
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void h264qpel_init_mmi(H264QpelContext *c, int bit_depth)
{
if (8 == bit_depth) {
c->put_h264_qpel_pixels_tab[0][0] = ff_put_h264_qpel16_mc00_mmi;
c->put_h264_qpel_pixels_tab[0][1] = ff_put_h264_qpel16_mc10_mmi;
c->put_h264_qpel_pixels_tab[0][2] = ff_put_h264_qpel16_mc20_mmi;
c->put_h264_qpel_pixels_tab[0][3] = ff_put_h264_qpel16_mc30_mmi;
c->put_h264_qpel_pixels_tab[0][4] = ff_put_h264_qpel16_mc01_mmi;
c->put_h264_qpel_pixels_tab[0][5] = ff_put_h264_qpel16_mc11_mmi;
c->put_h264_qpel_pixels_tab[0][6] = ff_put_h264_qpel16_mc21_mmi;
c->put_h264_qpel_pixels_tab[0][7] = ff_put_h264_qpel16_mc31_mmi;
c->put_h264_qpel_pixels_tab[0][8] = ff_put_h264_qpel16_mc02_mmi;
c->put_h264_qpel_pixels_tab[0][9] = ff_put_h264_qpel16_mc12_mmi;
c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_mmi;
c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_mmi;
c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_mmi;
c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_mmi;
c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_mmi;
c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_mmi;
c->put_h264_qpel_pixels_tab[1][0] = ff_put_h264_qpel8_mc00_mmi;
c->put_h264_qpel_pixels_tab[1][1] = ff_put_h264_qpel8_mc10_mmi;
c->put_h264_qpel_pixels_tab[1][2] = ff_put_h264_qpel8_mc20_mmi;
c->put_h264_qpel_pixels_tab[1][3] = ff_put_h264_qpel8_mc30_mmi;
c->put_h264_qpel_pixels_tab[1][4] = ff_put_h264_qpel8_mc01_mmi;
c->put_h264_qpel_pixels_tab[1][5] = ff_put_h264_qpel8_mc11_mmi;
c->put_h264_qpel_pixels_tab[1][6] = ff_put_h264_qpel8_mc21_mmi;
c->put_h264_qpel_pixels_tab[1][7] = ff_put_h264_qpel8_mc31_mmi;
c->put_h264_qpel_pixels_tab[1][8] = ff_put_h264_qpel8_mc02_mmi;
c->put_h264_qpel_pixels_tab[1][9] = ff_put_h264_qpel8_mc12_mmi;
c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_mmi;
c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_mmi;
c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_mmi;
c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_mmi;
c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_mmi;
c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_mmi;
c->put_h264_qpel_pixels_tab[2][0] = ff_put_h264_qpel4_mc00_mmi;
c->put_h264_qpel_pixels_tab[2][1] = ff_put_h264_qpel4_mc10_mmi;
c->put_h264_qpel_pixels_tab[2][2] = ff_put_h264_qpel4_mc20_mmi;
c->put_h264_qpel_pixels_tab[2][3] = ff_put_h264_qpel4_mc30_mmi;
c->put_h264_qpel_pixels_tab[2][4] = ff_put_h264_qpel4_mc01_mmi;
c->put_h264_qpel_pixels_tab[2][5] = ff_put_h264_qpel4_mc11_mmi;
c->put_h264_qpel_pixels_tab[2][6] = ff_put_h264_qpel4_mc21_mmi;
c->put_h264_qpel_pixels_tab[2][7] = ff_put_h264_qpel4_mc31_mmi;
c->put_h264_qpel_pixels_tab[2][8] = ff_put_h264_qpel4_mc02_mmi;
c->put_h264_qpel_pixels_tab[2][9] = ff_put_h264_qpel4_mc12_mmi;
c->put_h264_qpel_pixels_tab[2][10] = ff_put_h264_qpel4_mc22_mmi;
c->put_h264_qpel_pixels_tab[2][11] = ff_put_h264_qpel4_mc32_mmi;
c->put_h264_qpel_pixels_tab[2][12] = ff_put_h264_qpel4_mc03_mmi;
c->put_h264_qpel_pixels_tab[2][13] = ff_put_h264_qpel4_mc13_mmi;
c->put_h264_qpel_pixels_tab[2][14] = ff_put_h264_qpel4_mc23_mmi;
c->put_h264_qpel_pixels_tab[2][15] = ff_put_h264_qpel4_mc33_mmi;
c->avg_h264_qpel_pixels_tab[0][0] = ff_avg_h264_qpel16_mc00_mmi;
c->avg_h264_qpel_pixels_tab[0][1] = ff_avg_h264_qpel16_mc10_mmi;
c->avg_h264_qpel_pixels_tab[0][2] = ff_avg_h264_qpel16_mc20_mmi;
c->avg_h264_qpel_pixels_tab[0][3] = ff_avg_h264_qpel16_mc30_mmi;
c->avg_h264_qpel_pixels_tab[0][4] = ff_avg_h264_qpel16_mc01_mmi;
c->avg_h264_qpel_pixels_tab[0][5] = ff_avg_h264_qpel16_mc11_mmi;
c->avg_h264_qpel_pixels_tab[0][6] = ff_avg_h264_qpel16_mc21_mmi;
c->avg_h264_qpel_pixels_tab[0][7] = ff_avg_h264_qpel16_mc31_mmi;
c->avg_h264_qpel_pixels_tab[0][8] = ff_avg_h264_qpel16_mc02_mmi;
c->avg_h264_qpel_pixels_tab[0][9] = ff_avg_h264_qpel16_mc12_mmi;
c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_mmi;
c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_mmi;
c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_mmi;
c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_mmi;
c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_mmi;
c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_mmi;
c->avg_h264_qpel_pixels_tab[1][0] = ff_avg_h264_qpel8_mc00_mmi;
c->avg_h264_qpel_pixels_tab[1][1] = ff_avg_h264_qpel8_mc10_mmi;
c->avg_h264_qpel_pixels_tab[1][2] = ff_avg_h264_qpel8_mc20_mmi;
c->avg_h264_qpel_pixels_tab[1][3] = ff_avg_h264_qpel8_mc30_mmi;
c->avg_h264_qpel_pixels_tab[1][4] = ff_avg_h264_qpel8_mc01_mmi;
c->avg_h264_qpel_pixels_tab[1][5] = ff_avg_h264_qpel8_mc11_mmi;
c->avg_h264_qpel_pixels_tab[1][6] = ff_avg_h264_qpel8_mc21_mmi;
c->avg_h264_qpel_pixels_tab[1][7] = ff_avg_h264_qpel8_mc31_mmi;
c->avg_h264_qpel_pixels_tab[1][8] = ff_avg_h264_qpel8_mc02_mmi;
c->avg_h264_qpel_pixels_tab[1][9] = ff_avg_h264_qpel8_mc12_mmi;
c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_mmi;
c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_mmi;
c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_mmi;
c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_mmi;
c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_mmi;
c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_mmi;
c->avg_h264_qpel_pixels_tab[2][0] = ff_avg_h264_qpel4_mc00_mmi;
c->avg_h264_qpel_pixels_tab[2][1] = ff_avg_h264_qpel4_mc10_mmi;
c->avg_h264_qpel_pixels_tab[2][2] = ff_avg_h264_qpel4_mc20_mmi;
c->avg_h264_qpel_pixels_tab[2][3] = ff_avg_h264_qpel4_mc30_mmi;
c->avg_h264_qpel_pixels_tab[2][4] = ff_avg_h264_qpel4_mc01_mmi;
c->avg_h264_qpel_pixels_tab[2][5] = ff_avg_h264_qpel4_mc11_mmi;
c->avg_h264_qpel_pixels_tab[2][6] = ff_avg_h264_qpel4_mc21_mmi;
c->avg_h264_qpel_pixels_tab[2][7] = ff_avg_h264_qpel4_mc31_mmi;
c->avg_h264_qpel_pixels_tab[2][8] = ff_avg_h264_qpel4_mc02_mmi;
c->avg_h264_qpel_pixels_tab[2][9] = ff_avg_h264_qpel4_mc12_mmi;
c->avg_h264_qpel_pixels_tab[2][10] = ff_avg_h264_qpel4_mc22_mmi;
c->avg_h264_qpel_pixels_tab[2][11] = ff_avg_h264_qpel4_mc32_mmi;
c->avg_h264_qpel_pixels_tab[2][12] = ff_avg_h264_qpel4_mc03_mmi;
c->avg_h264_qpel_pixels_tab[2][13] = ff_avg_h264_qpel4_mc13_mmi;
c->avg_h264_qpel_pixels_tab[2][14] = ff_avg_h264_qpel4_mc23_mmi;
c->avg_h264_qpel_pixels_tab[2][15] = ff_avg_h264_qpel4_mc33_mmi;
}
}
#endif /* HAVE_MMI */
av_cold void ff_h264qpel_init_mips(H264QpelContext *c, int bit_depth)
{
#if HAVE_MMI
h264qpel_init_mmi(c, bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264qpel_init_msa(c, bit_depth);
#endif // #if HAVE_MSA
}

3134
externals/ffmpeg/libavcodec/mips/h264qpel_mmi.c vendored Executable file

File diff suppressed because it is too large Load Diff

5787
externals/ffmpeg/libavcodec/mips/h264qpel_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

1026
externals/ffmpeg/libavcodec/mips/hevc_idct_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_HEVC_MACROS_MSA_H
#define AVCODEC_MIPS_HEVC_MACROS_MSA_H
#define HEVC_FILT_8TAP_SH(in0, in1, in2, in3, \
filt0, filt1, filt2, filt3) \
( { \
v8i16 out_m; \
\
out_m = __msa_dotp_s_h((v16i8) in0, (v16i8) filt0); \
out_m = __msa_dpadd_s_h(out_m, (v16i8) in1, (v16i8) filt1); \
DPADD_SB2_SH(in2, in3, filt2, filt3, out_m, out_m); \
out_m; \
} )
#define HEVC_FILT_8TAP(in0, in1, in2, in3, \
filt0, filt1, filt2, filt3) \
( { \
v4i32 out_m; \
\
out_m = __msa_dotp_s_w((v8i16) in0, (v8i16) filt0); \
out_m = __msa_dpadd_s_w(out_m, (v8i16) in1, (v8i16) filt1); \
DPADD_SH2_SW(in2, in3, filt2, filt3, out_m, out_m); \
out_m; \
} )
#define HEVC_FILT_4TAP_SH(in0, in1, filt0, filt1) \
( { \
v8i16 out_m; \
\
out_m = __msa_dotp_s_h((v16i8) in0, (v16i8) filt0); \
out_m = __msa_dpadd_s_h(out_m, (v16i8) in1, (v16i8) filt1); \
out_m; \
} )
#define HEVC_FILT_4TAP(in0, in1, filt0, filt1) \
( { \
v4i32 out_m; \
\
out_m = __msa_dotp_s_w(in0, (v8i16) filt0); \
out_m = __msa_dpadd_s_w(out_m, in1, (v8i16) filt1); \
out_m; \
} )
#endif /* AVCODEC_MIPS_HEVC_MACROS_MSA_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,529 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavcodec/mips/hevcdsp_mips.h"
#if HAVE_MMI
static av_cold void hevc_dsp_init_mmi(HEVCDSPContext *c,
const int bit_depth)
{
if (8 == bit_depth) {
c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_mmi;
c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_mmi;
c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_mmi;
c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_mmi;
c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_mmi;
c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_mmi;
c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_mmi;
c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_mmi;
c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_mmi;
c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_mmi;
c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_mmi;
c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_mmi;
c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_mmi;
c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_mmi;
c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_mmi;
c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_mmi;
c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_qpel_bi_h4_8_mmi;
c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_qpel_bi_h8_8_mmi;
c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_qpel_bi_h12_8_mmi;
c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_qpel_bi_h16_8_mmi;
c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_qpel_bi_h24_8_mmi;
c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_qpel_bi_h32_8_mmi;
c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_qpel_bi_h48_8_mmi;
c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_qpel_bi_h64_8_mmi;
c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_qpel_bi_hv4_8_mmi;
c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_qpel_bi_hv8_8_mmi;
c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_qpel_bi_hv12_8_mmi;
c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_qpel_bi_hv16_8_mmi;
c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_qpel_bi_hv24_8_mmi;
c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_qpel_bi_hv32_8_mmi;
c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_qpel_bi_hv48_8_mmi;
c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_qpel_bi_hv64_8_mmi;
c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi;
c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi;
c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi;
c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi;
c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_pel_bi_pixels48_8_mmi;
c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_pel_bi_pixels64_8_mmi;
c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_pel_bi_pixels8_8_mmi;
c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_pel_bi_pixels16_8_mmi;
c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_pel_bi_pixels24_8_mmi;
c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_pel_bi_pixels32_8_mmi;
c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_epel_bi_hv4_8_mmi;
c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_epel_bi_hv8_8_mmi;
c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_epel_bi_hv12_8_mmi;
c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_epel_bi_hv16_8_mmi;
c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_epel_bi_hv24_8_mmi;
c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_epel_bi_hv32_8_mmi;
c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_qpel_uni_hv4_8_mmi;
c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_qpel_uni_hv8_8_mmi;
c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_qpel_uni_hv12_8_mmi;
c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_qpel_uni_hv16_8_mmi;
c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_qpel_uni_hv24_8_mmi;
c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_qpel_uni_hv32_8_mmi;
c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_qpel_uni_hv48_8_mmi;
c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_qpel_uni_hv64_8_mmi;
}
}
#endif // #if HAVE_MMI
#if HAVE_MSA
static av_cold void hevc_dsp_init_msa(HEVCDSPContext *c,
const int bit_depth)
{
if (8 == bit_depth) {
c->put_hevc_qpel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa;
c->put_hevc_qpel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa;
c->put_hevc_qpel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa;
c->put_hevc_qpel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa;
c->put_hevc_qpel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa;
c->put_hevc_qpel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa;
c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa;
c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_msa;
c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_msa;
c->put_hevc_qpel[1][0][1] = ff_hevc_put_hevc_qpel_h4_8_msa;
c->put_hevc_qpel[3][0][1] = ff_hevc_put_hevc_qpel_h8_8_msa;
c->put_hevc_qpel[4][0][1] = ff_hevc_put_hevc_qpel_h12_8_msa;
c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_8_msa;
c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_8_msa;
c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_msa;
c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_msa;
c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_msa;
c->put_hevc_qpel[1][1][0] = ff_hevc_put_hevc_qpel_v4_8_msa;
c->put_hevc_qpel[3][1][0] = ff_hevc_put_hevc_qpel_v8_8_msa;
c->put_hevc_qpel[4][1][0] = ff_hevc_put_hevc_qpel_v12_8_msa;
c->put_hevc_qpel[5][1][0] = ff_hevc_put_hevc_qpel_v16_8_msa;
c->put_hevc_qpel[6][1][0] = ff_hevc_put_hevc_qpel_v24_8_msa;
c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_8_msa;
c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_8_msa;
c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_8_msa;
c->put_hevc_qpel[1][1][1] = ff_hevc_put_hevc_qpel_hv4_8_msa;
c->put_hevc_qpel[3][1][1] = ff_hevc_put_hevc_qpel_hv8_8_msa;
c->put_hevc_qpel[4][1][1] = ff_hevc_put_hevc_qpel_hv12_8_msa;
c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_8_msa;
c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_8_msa;
c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_8_msa;
c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_8_msa;
c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_8_msa;
c->put_hevc_epel[1][0][0] = ff_hevc_put_hevc_pel_pixels4_8_msa;
c->put_hevc_epel[2][0][0] = ff_hevc_put_hevc_pel_pixels6_8_msa;
c->put_hevc_epel[3][0][0] = ff_hevc_put_hevc_pel_pixels8_8_msa;
c->put_hevc_epel[4][0][0] = ff_hevc_put_hevc_pel_pixels12_8_msa;
c->put_hevc_epel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_8_msa;
c->put_hevc_epel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_8_msa;
c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_msa;
c->put_hevc_epel[1][0][1] = ff_hevc_put_hevc_epel_h4_8_msa;
c->put_hevc_epel[2][0][1] = ff_hevc_put_hevc_epel_h6_8_msa;
c->put_hevc_epel[3][0][1] = ff_hevc_put_hevc_epel_h8_8_msa;
c->put_hevc_epel[4][0][1] = ff_hevc_put_hevc_epel_h12_8_msa;
c->put_hevc_epel[5][0][1] = ff_hevc_put_hevc_epel_h16_8_msa;
c->put_hevc_epel[6][0][1] = ff_hevc_put_hevc_epel_h24_8_msa;
c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_8_msa;
c->put_hevc_epel[1][1][0] = ff_hevc_put_hevc_epel_v4_8_msa;
c->put_hevc_epel[2][1][0] = ff_hevc_put_hevc_epel_v6_8_msa;
c->put_hevc_epel[3][1][0] = ff_hevc_put_hevc_epel_v8_8_msa;
c->put_hevc_epel[4][1][0] = ff_hevc_put_hevc_epel_v12_8_msa;
c->put_hevc_epel[5][1][0] = ff_hevc_put_hevc_epel_v16_8_msa;
c->put_hevc_epel[6][1][0] = ff_hevc_put_hevc_epel_v24_8_msa;
c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_8_msa;
c->put_hevc_epel[1][1][1] = ff_hevc_put_hevc_epel_hv4_8_msa;
c->put_hevc_epel[2][1][1] = ff_hevc_put_hevc_epel_hv6_8_msa;
c->put_hevc_epel[3][1][1] = ff_hevc_put_hevc_epel_hv8_8_msa;
c->put_hevc_epel[4][1][1] = ff_hevc_put_hevc_epel_hv12_8_msa;
c->put_hevc_epel[5][1][1] = ff_hevc_put_hevc_epel_hv16_8_msa;
c->put_hevc_epel[6][1][1] = ff_hevc_put_hevc_epel_hv24_8_msa;
c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_8_msa;
c->put_hevc_qpel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa;
c->put_hevc_qpel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa;
c->put_hevc_qpel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa;
c->put_hevc_qpel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa;
c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa;
c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_msa;
c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_msa;
c->put_hevc_qpel_uni[1][0][1] = ff_hevc_put_hevc_uni_qpel_h4_8_msa;
c->put_hevc_qpel_uni[3][0][1] = ff_hevc_put_hevc_uni_qpel_h8_8_msa;
c->put_hevc_qpel_uni[4][0][1] = ff_hevc_put_hevc_uni_qpel_h12_8_msa;
c->put_hevc_qpel_uni[5][0][1] = ff_hevc_put_hevc_uni_qpel_h16_8_msa;
c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_uni_qpel_h24_8_msa;
c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_8_msa;
c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_8_msa;
c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_8_msa;
c->put_hevc_qpel_uni[1][1][0] = ff_hevc_put_hevc_uni_qpel_v4_8_msa;
c->put_hevc_qpel_uni[3][1][0] = ff_hevc_put_hevc_uni_qpel_v8_8_msa;
c->put_hevc_qpel_uni[4][1][0] = ff_hevc_put_hevc_uni_qpel_v12_8_msa;
c->put_hevc_qpel_uni[5][1][0] = ff_hevc_put_hevc_uni_qpel_v16_8_msa;
c->put_hevc_qpel_uni[6][1][0] = ff_hevc_put_hevc_uni_qpel_v24_8_msa;
c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_8_msa;
c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_8_msa;
c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_8_msa;
c->put_hevc_qpel_uni[1][1][1] = ff_hevc_put_hevc_uni_qpel_hv4_8_msa;
c->put_hevc_qpel_uni[3][1][1] = ff_hevc_put_hevc_uni_qpel_hv8_8_msa;
c->put_hevc_qpel_uni[4][1][1] = ff_hevc_put_hevc_uni_qpel_hv12_8_msa;
c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_uni_qpel_hv16_8_msa;
c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_uni_qpel_hv24_8_msa;
c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_uni_qpel_hv32_8_msa;
c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_uni_qpel_hv48_8_msa;
c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_uni_qpel_hv64_8_msa;
c->put_hevc_epel_uni[3][0][0] = ff_hevc_put_hevc_uni_pel_pixels8_8_msa;
c->put_hevc_epel_uni[4][0][0] = ff_hevc_put_hevc_uni_pel_pixels12_8_msa;
c->put_hevc_epel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels16_8_msa;
c->put_hevc_epel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels24_8_msa;
c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_msa;
c->put_hevc_epel_uni[1][0][1] = ff_hevc_put_hevc_uni_epel_h4_8_msa;
c->put_hevc_epel_uni[2][0][1] = ff_hevc_put_hevc_uni_epel_h6_8_msa;
c->put_hevc_epel_uni[3][0][1] = ff_hevc_put_hevc_uni_epel_h8_8_msa;
c->put_hevc_epel_uni[4][0][1] = ff_hevc_put_hevc_uni_epel_h12_8_msa;
c->put_hevc_epel_uni[5][0][1] = ff_hevc_put_hevc_uni_epel_h16_8_msa;
c->put_hevc_epel_uni[6][0][1] = ff_hevc_put_hevc_uni_epel_h24_8_msa;
c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_8_msa;
c->put_hevc_epel_uni[1][1][0] = ff_hevc_put_hevc_uni_epel_v4_8_msa;
c->put_hevc_epel_uni[2][1][0] = ff_hevc_put_hevc_uni_epel_v6_8_msa;
c->put_hevc_epel_uni[3][1][0] = ff_hevc_put_hevc_uni_epel_v8_8_msa;
c->put_hevc_epel_uni[4][1][0] = ff_hevc_put_hevc_uni_epel_v12_8_msa;
c->put_hevc_epel_uni[5][1][0] = ff_hevc_put_hevc_uni_epel_v16_8_msa;
c->put_hevc_epel_uni[6][1][0] = ff_hevc_put_hevc_uni_epel_v24_8_msa;
c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_8_msa;
c->put_hevc_epel_uni[1][1][1] = ff_hevc_put_hevc_uni_epel_hv4_8_msa;
c->put_hevc_epel_uni[2][1][1] = ff_hevc_put_hevc_uni_epel_hv6_8_msa;
c->put_hevc_epel_uni[3][1][1] = ff_hevc_put_hevc_uni_epel_hv8_8_msa;
c->put_hevc_epel_uni[4][1][1] = ff_hevc_put_hevc_uni_epel_hv12_8_msa;
c->put_hevc_epel_uni[5][1][1] = ff_hevc_put_hevc_uni_epel_hv16_8_msa;
c->put_hevc_epel_uni[6][1][1] = ff_hevc_put_hevc_uni_epel_hv24_8_msa;
c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_8_msa;
c->put_hevc_qpel_uni_w[1][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa;
c->put_hevc_qpel_uni_w[3][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa;
c->put_hevc_qpel_uni_w[4][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa;
c->put_hevc_qpel_uni_w[5][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa;
c->put_hevc_qpel_uni_w[6][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa;
c->put_hevc_qpel_uni_w[7][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa;
c->put_hevc_qpel_uni_w[8][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels48_8_msa;
c->put_hevc_qpel_uni_w[9][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels64_8_msa;
c->put_hevc_qpel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_qpel_h4_8_msa;
c->put_hevc_qpel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_qpel_h8_8_msa;
c->put_hevc_qpel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_qpel_h12_8_msa;
c->put_hevc_qpel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_qpel_h16_8_msa;
c->put_hevc_qpel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_qpel_h24_8_msa;
c->put_hevc_qpel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_qpel_h32_8_msa;
c->put_hevc_qpel_uni_w[8][0][1] = ff_hevc_put_hevc_uni_w_qpel_h48_8_msa;
c->put_hevc_qpel_uni_w[9][0][1] = ff_hevc_put_hevc_uni_w_qpel_h64_8_msa;
c->put_hevc_qpel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_qpel_v4_8_msa;
c->put_hevc_qpel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_qpel_v8_8_msa;
c->put_hevc_qpel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_qpel_v12_8_msa;
c->put_hevc_qpel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_qpel_v16_8_msa;
c->put_hevc_qpel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_qpel_v24_8_msa;
c->put_hevc_qpel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_qpel_v32_8_msa;
c->put_hevc_qpel_uni_w[8][1][0] = ff_hevc_put_hevc_uni_w_qpel_v48_8_msa;
c->put_hevc_qpel_uni_w[9][1][0] = ff_hevc_put_hevc_uni_w_qpel_v64_8_msa;
c->put_hevc_qpel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv4_8_msa;
c->put_hevc_qpel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_qpel_hv8_8_msa;
c->put_hevc_qpel_uni_w[4][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv12_8_msa;
c->put_hevc_qpel_uni_w[5][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv16_8_msa;
c->put_hevc_qpel_uni_w[6][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv24_8_msa;
c->put_hevc_qpel_uni_w[7][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv32_8_msa;
c->put_hevc_qpel_uni_w[8][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv48_8_msa;
c->put_hevc_qpel_uni_w[9][1][1] =
ff_hevc_put_hevc_uni_w_qpel_hv64_8_msa;
c->put_hevc_epel_uni_w[1][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels4_8_msa;
c->put_hevc_epel_uni_w[2][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels6_8_msa;
c->put_hevc_epel_uni_w[3][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels8_8_msa;
c->put_hevc_epel_uni_w[4][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels12_8_msa;
c->put_hevc_epel_uni_w[5][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels16_8_msa;
c->put_hevc_epel_uni_w[6][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels24_8_msa;
c->put_hevc_epel_uni_w[7][0][0] =
ff_hevc_put_hevc_uni_w_pel_pixels32_8_msa;
c->put_hevc_epel_uni_w[1][0][1] = ff_hevc_put_hevc_uni_w_epel_h4_8_msa;
c->put_hevc_epel_uni_w[2][0][1] = ff_hevc_put_hevc_uni_w_epel_h6_8_msa;
c->put_hevc_epel_uni_w[3][0][1] = ff_hevc_put_hevc_uni_w_epel_h8_8_msa;
c->put_hevc_epel_uni_w[4][0][1] = ff_hevc_put_hevc_uni_w_epel_h12_8_msa;
c->put_hevc_epel_uni_w[5][0][1] = ff_hevc_put_hevc_uni_w_epel_h16_8_msa;
c->put_hevc_epel_uni_w[6][0][1] = ff_hevc_put_hevc_uni_w_epel_h24_8_msa;
c->put_hevc_epel_uni_w[7][0][1] = ff_hevc_put_hevc_uni_w_epel_h32_8_msa;
c->put_hevc_epel_uni_w[1][1][0] = ff_hevc_put_hevc_uni_w_epel_v4_8_msa;
c->put_hevc_epel_uni_w[2][1][0] = ff_hevc_put_hevc_uni_w_epel_v6_8_msa;
c->put_hevc_epel_uni_w[3][1][0] = ff_hevc_put_hevc_uni_w_epel_v8_8_msa;
c->put_hevc_epel_uni_w[4][1][0] = ff_hevc_put_hevc_uni_w_epel_v12_8_msa;
c->put_hevc_epel_uni_w[5][1][0] = ff_hevc_put_hevc_uni_w_epel_v16_8_msa;
c->put_hevc_epel_uni_w[6][1][0] = ff_hevc_put_hevc_uni_w_epel_v24_8_msa;
c->put_hevc_epel_uni_w[7][1][0] = ff_hevc_put_hevc_uni_w_epel_v32_8_msa;
c->put_hevc_epel_uni_w[1][1][1] = ff_hevc_put_hevc_uni_w_epel_hv4_8_msa;
c->put_hevc_epel_uni_w[2][1][1] = ff_hevc_put_hevc_uni_w_epel_hv6_8_msa;
c->put_hevc_epel_uni_w[3][1][1] = ff_hevc_put_hevc_uni_w_epel_hv8_8_msa;
c->put_hevc_epel_uni_w[4][1][1] =
ff_hevc_put_hevc_uni_w_epel_hv12_8_msa;
c->put_hevc_epel_uni_w[5][1][1] =
ff_hevc_put_hevc_uni_w_epel_hv16_8_msa;
c->put_hevc_epel_uni_w[6][1][1] =
ff_hevc_put_hevc_uni_w_epel_hv24_8_msa;
c->put_hevc_epel_uni_w[7][1][1] =
ff_hevc_put_hevc_uni_w_epel_hv32_8_msa;
c->put_hevc_qpel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa;
c->put_hevc_qpel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa;
c->put_hevc_qpel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa;
c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa;
c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa;
c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa;
c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_msa;
c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_msa;
c->put_hevc_qpel_bi[1][0][1] = ff_hevc_put_hevc_bi_qpel_h4_8_msa;
c->put_hevc_qpel_bi[3][0][1] = ff_hevc_put_hevc_bi_qpel_h8_8_msa;
c->put_hevc_qpel_bi[4][0][1] = ff_hevc_put_hevc_bi_qpel_h12_8_msa;
c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_bi_qpel_h16_8_msa;
c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_bi_qpel_h24_8_msa;
c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_8_msa;
c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_8_msa;
c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_8_msa;
c->put_hevc_qpel_bi[1][1][0] = ff_hevc_put_hevc_bi_qpel_v4_8_msa;
c->put_hevc_qpel_bi[3][1][0] = ff_hevc_put_hevc_bi_qpel_v8_8_msa;
c->put_hevc_qpel_bi[4][1][0] = ff_hevc_put_hevc_bi_qpel_v12_8_msa;
c->put_hevc_qpel_bi[5][1][0] = ff_hevc_put_hevc_bi_qpel_v16_8_msa;
c->put_hevc_qpel_bi[6][1][0] = ff_hevc_put_hevc_bi_qpel_v24_8_msa;
c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_8_msa;
c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_8_msa;
c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_8_msa;
c->put_hevc_qpel_bi[1][1][1] = ff_hevc_put_hevc_bi_qpel_hv4_8_msa;
c->put_hevc_qpel_bi[3][1][1] = ff_hevc_put_hevc_bi_qpel_hv8_8_msa;
c->put_hevc_qpel_bi[4][1][1] = ff_hevc_put_hevc_bi_qpel_hv12_8_msa;
c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_bi_qpel_hv16_8_msa;
c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_bi_qpel_hv24_8_msa;
c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_bi_qpel_hv32_8_msa;
c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_bi_qpel_hv48_8_msa;
c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_bi_qpel_hv64_8_msa;
c->put_hevc_epel_bi[1][0][0] = ff_hevc_put_hevc_bi_pel_pixels4_8_msa;
c->put_hevc_epel_bi[2][0][0] = ff_hevc_put_hevc_bi_pel_pixels6_8_msa;
c->put_hevc_epel_bi[3][0][0] = ff_hevc_put_hevc_bi_pel_pixels8_8_msa;
c->put_hevc_epel_bi[4][0][0] = ff_hevc_put_hevc_bi_pel_pixels12_8_msa;
c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_8_msa;
c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_8_msa;
c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_msa;
c->put_hevc_epel_bi[1][0][1] = ff_hevc_put_hevc_bi_epel_h4_8_msa;
c->put_hevc_epel_bi[2][0][1] = ff_hevc_put_hevc_bi_epel_h6_8_msa;
c->put_hevc_epel_bi[3][0][1] = ff_hevc_put_hevc_bi_epel_h8_8_msa;
c->put_hevc_epel_bi[4][0][1] = ff_hevc_put_hevc_bi_epel_h12_8_msa;
c->put_hevc_epel_bi[5][0][1] = ff_hevc_put_hevc_bi_epel_h16_8_msa;
c->put_hevc_epel_bi[6][0][1] = ff_hevc_put_hevc_bi_epel_h24_8_msa;
c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_8_msa;
c->put_hevc_epel_bi[1][1][0] = ff_hevc_put_hevc_bi_epel_v4_8_msa;
c->put_hevc_epel_bi[2][1][0] = ff_hevc_put_hevc_bi_epel_v6_8_msa;
c->put_hevc_epel_bi[3][1][0] = ff_hevc_put_hevc_bi_epel_v8_8_msa;
c->put_hevc_epel_bi[4][1][0] = ff_hevc_put_hevc_bi_epel_v12_8_msa;
c->put_hevc_epel_bi[5][1][0] = ff_hevc_put_hevc_bi_epel_v16_8_msa;
c->put_hevc_epel_bi[6][1][0] = ff_hevc_put_hevc_bi_epel_v24_8_msa;
c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_8_msa;
c->put_hevc_epel_bi[1][1][1] = ff_hevc_put_hevc_bi_epel_hv4_8_msa;
c->put_hevc_epel_bi[2][1][1] = ff_hevc_put_hevc_bi_epel_hv6_8_msa;
c->put_hevc_epel_bi[3][1][1] = ff_hevc_put_hevc_bi_epel_hv8_8_msa;
c->put_hevc_epel_bi[4][1][1] = ff_hevc_put_hevc_bi_epel_hv12_8_msa;
c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_bi_epel_hv16_8_msa;
c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_bi_epel_hv24_8_msa;
c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_8_msa;
c->put_hevc_qpel_bi_w[1][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa;
c->put_hevc_qpel_bi_w[3][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa;
c->put_hevc_qpel_bi_w[4][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa;
c->put_hevc_qpel_bi_w[5][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa;
c->put_hevc_qpel_bi_w[6][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa;
c->put_hevc_qpel_bi_w[7][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa;
c->put_hevc_qpel_bi_w[8][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels48_8_msa;
c->put_hevc_qpel_bi_w[9][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels64_8_msa;
c->put_hevc_qpel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_qpel_h4_8_msa;
c->put_hevc_qpel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_qpel_h8_8_msa;
c->put_hevc_qpel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_qpel_h12_8_msa;
c->put_hevc_qpel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_qpel_h16_8_msa;
c->put_hevc_qpel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_qpel_h24_8_msa;
c->put_hevc_qpel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_qpel_h32_8_msa;
c->put_hevc_qpel_bi_w[8][0][1] = ff_hevc_put_hevc_bi_w_qpel_h48_8_msa;
c->put_hevc_qpel_bi_w[9][0][1] = ff_hevc_put_hevc_bi_w_qpel_h64_8_msa;
c->put_hevc_qpel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_qpel_v4_8_msa;
c->put_hevc_qpel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_qpel_v8_8_msa;
c->put_hevc_qpel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_qpel_v12_8_msa;
c->put_hevc_qpel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_qpel_v16_8_msa;
c->put_hevc_qpel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_qpel_v24_8_msa;
c->put_hevc_qpel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_qpel_v32_8_msa;
c->put_hevc_qpel_bi_w[8][1][0] = ff_hevc_put_hevc_bi_w_qpel_v48_8_msa;
c->put_hevc_qpel_bi_w[9][1][0] = ff_hevc_put_hevc_bi_w_qpel_v64_8_msa;
c->put_hevc_qpel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv4_8_msa;
c->put_hevc_qpel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv8_8_msa;
c->put_hevc_qpel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv12_8_msa;
c->put_hevc_qpel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv16_8_msa;
c->put_hevc_qpel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv24_8_msa;
c->put_hevc_qpel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv32_8_msa;
c->put_hevc_qpel_bi_w[8][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv48_8_msa;
c->put_hevc_qpel_bi_w[9][1][1] = ff_hevc_put_hevc_bi_w_qpel_hv64_8_msa;
c->put_hevc_epel_bi_w[1][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels4_8_msa;
c->put_hevc_epel_bi_w[2][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels6_8_msa;
c->put_hevc_epel_bi_w[3][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels8_8_msa;
c->put_hevc_epel_bi_w[4][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels12_8_msa;
c->put_hevc_epel_bi_w[5][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels16_8_msa;
c->put_hevc_epel_bi_w[6][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels24_8_msa;
c->put_hevc_epel_bi_w[7][0][0] =
ff_hevc_put_hevc_bi_w_pel_pixels32_8_msa;
c->put_hevc_epel_bi_w[1][0][1] = ff_hevc_put_hevc_bi_w_epel_h4_8_msa;
c->put_hevc_epel_bi_w[2][0][1] = ff_hevc_put_hevc_bi_w_epel_h6_8_msa;
c->put_hevc_epel_bi_w[3][0][1] = ff_hevc_put_hevc_bi_w_epel_h8_8_msa;
c->put_hevc_epel_bi_w[4][0][1] = ff_hevc_put_hevc_bi_w_epel_h12_8_msa;
c->put_hevc_epel_bi_w[5][0][1] = ff_hevc_put_hevc_bi_w_epel_h16_8_msa;
c->put_hevc_epel_bi_w[6][0][1] = ff_hevc_put_hevc_bi_w_epel_h24_8_msa;
c->put_hevc_epel_bi_w[7][0][1] = ff_hevc_put_hevc_bi_w_epel_h32_8_msa;
c->put_hevc_epel_bi_w[1][1][0] = ff_hevc_put_hevc_bi_w_epel_v4_8_msa;
c->put_hevc_epel_bi_w[2][1][0] = ff_hevc_put_hevc_bi_w_epel_v6_8_msa;
c->put_hevc_epel_bi_w[3][1][0] = ff_hevc_put_hevc_bi_w_epel_v8_8_msa;
c->put_hevc_epel_bi_w[4][1][0] = ff_hevc_put_hevc_bi_w_epel_v12_8_msa;
c->put_hevc_epel_bi_w[5][1][0] = ff_hevc_put_hevc_bi_w_epel_v16_8_msa;
c->put_hevc_epel_bi_w[6][1][0] = ff_hevc_put_hevc_bi_w_epel_v24_8_msa;
c->put_hevc_epel_bi_w[7][1][0] = ff_hevc_put_hevc_bi_w_epel_v32_8_msa;
c->put_hevc_epel_bi_w[1][1][1] = ff_hevc_put_hevc_bi_w_epel_hv4_8_msa;
c->put_hevc_epel_bi_w[2][1][1] = ff_hevc_put_hevc_bi_w_epel_hv6_8_msa;
c->put_hevc_epel_bi_w[3][1][1] = ff_hevc_put_hevc_bi_w_epel_hv8_8_msa;
c->put_hevc_epel_bi_w[4][1][1] = ff_hevc_put_hevc_bi_w_epel_hv12_8_msa;
c->put_hevc_epel_bi_w[5][1][1] = ff_hevc_put_hevc_bi_w_epel_hv16_8_msa;
c->put_hevc_epel_bi_w[6][1][1] = ff_hevc_put_hevc_bi_w_epel_hv24_8_msa;
c->put_hevc_epel_bi_w[7][1][1] = ff_hevc_put_hevc_bi_w_epel_hv32_8_msa;
c->sao_band_filter[0] =
c->sao_band_filter[1] =
c->sao_band_filter[2] =
c->sao_band_filter[3] =
c->sao_band_filter[4] = ff_hevc_sao_band_filter_0_8_msa;
c->sao_edge_filter[0] =
c->sao_edge_filter[1] =
c->sao_edge_filter[2] =
c->sao_edge_filter[3] =
c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_8_msa;
c->hevc_h_loop_filter_luma = ff_hevc_loop_filter_luma_h_8_msa;
c->hevc_v_loop_filter_luma = ff_hevc_loop_filter_luma_v_8_msa;
c->hevc_h_loop_filter_chroma = ff_hevc_loop_filter_chroma_h_8_msa;
c->hevc_v_loop_filter_chroma = ff_hevc_loop_filter_chroma_v_8_msa;
c->hevc_h_loop_filter_luma_c = ff_hevc_loop_filter_luma_h_8_msa;
c->hevc_v_loop_filter_luma_c = ff_hevc_loop_filter_luma_v_8_msa;
c->hevc_h_loop_filter_chroma_c =
ff_hevc_loop_filter_chroma_h_8_msa;
c->hevc_v_loop_filter_chroma_c =
ff_hevc_loop_filter_chroma_v_8_msa;
c->idct[0] = ff_hevc_idct_4x4_msa;
c->idct[1] = ff_hevc_idct_8x8_msa;
c->idct[2] = ff_hevc_idct_16x16_msa;
c->idct[3] = ff_hevc_idct_32x32_msa;
c->idct_dc[0] = ff_hevc_idct_dc_4x4_msa;
c->idct_dc[1] = ff_hevc_idct_dc_8x8_msa;
c->idct_dc[2] = ff_hevc_idct_dc_16x16_msa;
c->idct_dc[3] = ff_hevc_idct_dc_32x32_msa;
c->add_residual[0] = ff_hevc_addblk_4x4_msa;
c->add_residual[1] = ff_hevc_addblk_8x8_msa;
c->add_residual[2] = ff_hevc_addblk_16x16_msa;
c->add_residual[3] = ff_hevc_addblk_32x32_msa;
c->transform_4x4_luma = ff_hevc_idct_luma_4x4_msa;
}
}
#endif // #if HAVE_MSA
void ff_hevc_dsp_init_mips(HEVCDSPContext *c, const int bit_depth)
{
#if HAVE_MMI
hevc_dsp_init_mmi(c, bit_depth);
#endif // #if HAVE_MMI
#if HAVE_MSA
hevc_dsp_init_msa(c, bit_depth);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,573 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_HEVCDSP_MIPS_H
#define AVCODEC_MIPS_HEVCDSP_MIPS_H
#include "libavcodec/hevcdsp.h"
#define MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_##PEL##_##DIR##WIDTH##_8_msa(int16_t *dst, \
uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
MC(pel, pixels, 4);
MC(pel, pixels, 6);
MC(pel, pixels, 8);
MC(pel, pixels, 12);
MC(pel, pixels, 16);
MC(pel, pixels, 24);
MC(pel, pixels, 32);
MC(pel, pixels, 48);
MC(pel, pixels, 64);
MC(qpel, h, 4);
MC(qpel, h, 8);
MC(qpel, h, 12);
MC(qpel, h, 16);
MC(qpel, h, 24);
MC(qpel, h, 32);
MC(qpel, h, 48);
MC(qpel, h, 64);
MC(qpel, v, 4);
MC(qpel, v, 8);
MC(qpel, v, 12);
MC(qpel, v, 16);
MC(qpel, v, 24);
MC(qpel, v, 32);
MC(qpel, v, 48);
MC(qpel, v, 64);
MC(qpel, hv, 4);
MC(qpel, hv, 8);
MC(qpel, hv, 12);
MC(qpel, hv, 16);
MC(qpel, hv, 24);
MC(qpel, hv, 32);
MC(qpel, hv, 48);
MC(qpel, hv, 64);
MC(epel, h, 4);
MC(epel, h, 6);
MC(epel, h, 8);
MC(epel, h, 12);
MC(epel, h, 16);
MC(epel, h, 24);
MC(epel, h, 32);
MC(epel, h, 48);
MC(epel, h, 64);
MC(epel, v, 4);
MC(epel, v, 6);
MC(epel, v, 8);
MC(epel, v, 12);
MC(epel, v, 16);
MC(epel, v, 24);
MC(epel, v, 32);
MC(epel, v, 48);
MC(epel, v, 64);
MC(epel, hv, 4);
MC(epel, hv, 6);
MC(epel, hv, 8);
MC(epel, hv, 12);
MC(epel, hv, 16);
MC(epel, hv, 24);
MC(epel, hv, 32);
MC(epel, hv, 48);
MC(epel, hv, 64);
#undef MC
#define UNI_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_uni_##PEL##_##DIR##WIDTH##_8_msa(uint8_t *dst, \
ptrdiff_t dst_stride, \
uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
UNI_MC(pel, pixels, 4);
UNI_MC(pel, pixels, 6);
UNI_MC(pel, pixels, 8);
UNI_MC(pel, pixels, 12);
UNI_MC(pel, pixels, 16);
UNI_MC(pel, pixels, 24);
UNI_MC(pel, pixels, 32);
UNI_MC(pel, pixels, 48);
UNI_MC(pel, pixels, 64);
UNI_MC(qpel, h, 4);
UNI_MC(qpel, h, 8);
UNI_MC(qpel, h, 12);
UNI_MC(qpel, h, 16);
UNI_MC(qpel, h, 24);
UNI_MC(qpel, h, 32);
UNI_MC(qpel, h, 48);
UNI_MC(qpel, h, 64);
UNI_MC(qpel, v, 4);
UNI_MC(qpel, v, 8);
UNI_MC(qpel, v, 12);
UNI_MC(qpel, v, 16);
UNI_MC(qpel, v, 24);
UNI_MC(qpel, v, 32);
UNI_MC(qpel, v, 48);
UNI_MC(qpel, v, 64);
UNI_MC(qpel, hv, 4);
UNI_MC(qpel, hv, 8);
UNI_MC(qpel, hv, 12);
UNI_MC(qpel, hv, 16);
UNI_MC(qpel, hv, 24);
UNI_MC(qpel, hv, 32);
UNI_MC(qpel, hv, 48);
UNI_MC(qpel, hv, 64);
UNI_MC(epel, h, 4);
UNI_MC(epel, h, 6);
UNI_MC(epel, h, 8);
UNI_MC(epel, h, 12);
UNI_MC(epel, h, 16);
UNI_MC(epel, h, 24);
UNI_MC(epel, h, 32);
UNI_MC(epel, h, 48);
UNI_MC(epel, h, 64);
UNI_MC(epel, v, 4);
UNI_MC(epel, v, 6);
UNI_MC(epel, v, 8);
UNI_MC(epel, v, 12);
UNI_MC(epel, v, 16);
UNI_MC(epel, v, 24);
UNI_MC(epel, v, 32);
UNI_MC(epel, v, 48);
UNI_MC(epel, v, 64);
UNI_MC(epel, hv, 4);
UNI_MC(epel, hv, 6);
UNI_MC(epel, hv, 8);
UNI_MC(epel, hv, 12);
UNI_MC(epel, hv, 16);
UNI_MC(epel, hv, 24);
UNI_MC(epel, hv, 32);
UNI_MC(epel, hv, 48);
UNI_MC(epel, hv, 64);
#undef UNI_MC
#define UNI_W_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_uni_w_##PEL##_##DIR##WIDTH##_8_msa(uint8_t *dst, \
ptrdiff_t \
dst_stride, \
uint8_t *src, \
ptrdiff_t \
src_stride, \
int height, \
int denom, \
int weight, \
int offset, \
intptr_t mx, \
intptr_t my, \
int width)
UNI_W_MC(pel, pixels, 4);
UNI_W_MC(pel, pixels, 6);
UNI_W_MC(pel, pixels, 8);
UNI_W_MC(pel, pixels, 12);
UNI_W_MC(pel, pixels, 16);
UNI_W_MC(pel, pixels, 24);
UNI_W_MC(pel, pixels, 32);
UNI_W_MC(pel, pixels, 48);
UNI_W_MC(pel, pixels, 64);
UNI_W_MC(qpel, h, 4);
UNI_W_MC(qpel, h, 8);
UNI_W_MC(qpel, h, 12);
UNI_W_MC(qpel, h, 16);
UNI_W_MC(qpel, h, 24);
UNI_W_MC(qpel, h, 32);
UNI_W_MC(qpel, h, 48);
UNI_W_MC(qpel, h, 64);
UNI_W_MC(qpel, v, 4);
UNI_W_MC(qpel, v, 8);
UNI_W_MC(qpel, v, 12);
UNI_W_MC(qpel, v, 16);
UNI_W_MC(qpel, v, 24);
UNI_W_MC(qpel, v, 32);
UNI_W_MC(qpel, v, 48);
UNI_W_MC(qpel, v, 64);
UNI_W_MC(qpel, hv, 4);
UNI_W_MC(qpel, hv, 8);
UNI_W_MC(qpel, hv, 12);
UNI_W_MC(qpel, hv, 16);
UNI_W_MC(qpel, hv, 24);
UNI_W_MC(qpel, hv, 32);
UNI_W_MC(qpel, hv, 48);
UNI_W_MC(qpel, hv, 64);
UNI_W_MC(epel, h, 4);
UNI_W_MC(epel, h, 6);
UNI_W_MC(epel, h, 8);
UNI_W_MC(epel, h, 12);
UNI_W_MC(epel, h, 16);
UNI_W_MC(epel, h, 24);
UNI_W_MC(epel, h, 32);
UNI_W_MC(epel, h, 48);
UNI_W_MC(epel, h, 64);
UNI_W_MC(epel, v, 4);
UNI_W_MC(epel, v, 6);
UNI_W_MC(epel, v, 8);
UNI_W_MC(epel, v, 12);
UNI_W_MC(epel, v, 16);
UNI_W_MC(epel, v, 24);
UNI_W_MC(epel, v, 32);
UNI_W_MC(epel, v, 48);
UNI_W_MC(epel, v, 64);
UNI_W_MC(epel, hv, 4);
UNI_W_MC(epel, hv, 6);
UNI_W_MC(epel, hv, 8);
UNI_W_MC(epel, hv, 12);
UNI_W_MC(epel, hv, 16);
UNI_W_MC(epel, hv, 24);
UNI_W_MC(epel, hv, 32);
UNI_W_MC(epel, hv, 48);
UNI_W_MC(epel, hv, 64);
#undef UNI_W_MC
#define BI_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_bi_##PEL##_##DIR##WIDTH##_8_msa(uint8_t *dst, \
ptrdiff_t dst_stride, \
uint8_t *src, \
ptrdiff_t src_stride, \
int16_t *src_16bit, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
BI_MC(pel, pixels, 4);
BI_MC(pel, pixels, 6);
BI_MC(pel, pixels, 8);
BI_MC(pel, pixels, 12);
BI_MC(pel, pixels, 16);
BI_MC(pel, pixels, 24);
BI_MC(pel, pixels, 32);
BI_MC(pel, pixels, 48);
BI_MC(pel, pixels, 64);
BI_MC(qpel, h, 4);
BI_MC(qpel, h, 8);
BI_MC(qpel, h, 12);
BI_MC(qpel, h, 16);
BI_MC(qpel, h, 24);
BI_MC(qpel, h, 32);
BI_MC(qpel, h, 48);
BI_MC(qpel, h, 64);
BI_MC(qpel, v, 4);
BI_MC(qpel, v, 8);
BI_MC(qpel, v, 12);
BI_MC(qpel, v, 16);
BI_MC(qpel, v, 24);
BI_MC(qpel, v, 32);
BI_MC(qpel, v, 48);
BI_MC(qpel, v, 64);
BI_MC(qpel, hv, 4);
BI_MC(qpel, hv, 8);
BI_MC(qpel, hv, 12);
BI_MC(qpel, hv, 16);
BI_MC(qpel, hv, 24);
BI_MC(qpel, hv, 32);
BI_MC(qpel, hv, 48);
BI_MC(qpel, hv, 64);
BI_MC(epel, h, 4);
BI_MC(epel, h, 6);
BI_MC(epel, h, 8);
BI_MC(epel, h, 12);
BI_MC(epel, h, 16);
BI_MC(epel, h, 24);
BI_MC(epel, h, 32);
BI_MC(epel, h, 48);
BI_MC(epel, h, 64);
BI_MC(epel, v, 4);
BI_MC(epel, v, 6);
BI_MC(epel, v, 8);
BI_MC(epel, v, 12);
BI_MC(epel, v, 16);
BI_MC(epel, v, 24);
BI_MC(epel, v, 32);
BI_MC(epel, v, 48);
BI_MC(epel, v, 64);
BI_MC(epel, hv, 4);
BI_MC(epel, hv, 6);
BI_MC(epel, hv, 8);
BI_MC(epel, hv, 12);
BI_MC(epel, hv, 16);
BI_MC(epel, hv, 24);
BI_MC(epel, hv, 32);
BI_MC(epel, hv, 48);
BI_MC(epel, hv, 64);
#undef BI_MC
#define BI_W_MC(PEL, DIR, WIDTH) \
void ff_hevc_put_hevc_bi_w_##PEL##_##DIR##WIDTH##_8_msa(uint8_t *dst, \
ptrdiff_t \
dst_stride, \
uint8_t *src, \
ptrdiff_t \
src_stride, \
int16_t *src_16bit, \
int height, \
int denom, \
int weight0, \
int weight1, \
int offset0, \
int offset1, \
intptr_t mx, \
intptr_t my, \
int width)
BI_W_MC(pel, pixels, 4);
BI_W_MC(pel, pixels, 6);
BI_W_MC(pel, pixels, 8);
BI_W_MC(pel, pixels, 12);
BI_W_MC(pel, pixels, 16);
BI_W_MC(pel, pixels, 24);
BI_W_MC(pel, pixels, 32);
BI_W_MC(pel, pixels, 48);
BI_W_MC(pel, pixels, 64);
BI_W_MC(qpel, h, 4);
BI_W_MC(qpel, h, 8);
BI_W_MC(qpel, h, 12);
BI_W_MC(qpel, h, 16);
BI_W_MC(qpel, h, 24);
BI_W_MC(qpel, h, 32);
BI_W_MC(qpel, h, 48);
BI_W_MC(qpel, h, 64);
BI_W_MC(qpel, v, 4);
BI_W_MC(qpel, v, 8);
BI_W_MC(qpel, v, 12);
BI_W_MC(qpel, v, 16);
BI_W_MC(qpel, v, 24);
BI_W_MC(qpel, v, 32);
BI_W_MC(qpel, v, 48);
BI_W_MC(qpel, v, 64);
BI_W_MC(qpel, hv, 4);
BI_W_MC(qpel, hv, 8);
BI_W_MC(qpel, hv, 12);
BI_W_MC(qpel, hv, 16);
BI_W_MC(qpel, hv, 24);
BI_W_MC(qpel, hv, 32);
BI_W_MC(qpel, hv, 48);
BI_W_MC(qpel, hv, 64);
BI_W_MC(epel, h, 4);
BI_W_MC(epel, h, 6);
BI_W_MC(epel, h, 8);
BI_W_MC(epel, h, 12);
BI_W_MC(epel, h, 16);
BI_W_MC(epel, h, 24);
BI_W_MC(epel, h, 32);
BI_W_MC(epel, h, 48);
BI_W_MC(epel, h, 64);
BI_W_MC(epel, v, 4);
BI_W_MC(epel, v, 6);
BI_W_MC(epel, v, 8);
BI_W_MC(epel, v, 12);
BI_W_MC(epel, v, 16);
BI_W_MC(epel, v, 24);
BI_W_MC(epel, v, 32);
BI_W_MC(epel, v, 48);
BI_W_MC(epel, v, 64);
BI_W_MC(epel, hv, 4);
BI_W_MC(epel, hv, 6);
BI_W_MC(epel, hv, 8);
BI_W_MC(epel, hv, 12);
BI_W_MC(epel, hv, 16);
BI_W_MC(epel, hv, 24);
BI_W_MC(epel, hv, 32);
BI_W_MC(epel, hv, 48);
BI_W_MC(epel, hv, 64);
#undef BI_W_MC
void ff_hevc_loop_filter_luma_h_8_msa(uint8_t *src,
ptrdiff_t src_stride,
int32_t beta, int32_t *tc,
uint8_t *no_p, uint8_t *no_q);
void ff_hevc_loop_filter_luma_v_8_msa(uint8_t *src,
ptrdiff_t src_stride,
int32_t beta, int32_t *tc,
uint8_t *no_p, uint8_t *no_q);
void ff_hevc_loop_filter_chroma_h_8_msa(uint8_t *src,
ptrdiff_t src_stride,
int32_t *tc, uint8_t *no_p,
uint8_t *no_q);
void ff_hevc_loop_filter_chroma_v_8_msa(uint8_t *src,
ptrdiff_t src_stride,
int32_t *tc, uint8_t *no_p,
uint8_t *no_q);
void ff_hevc_sao_band_filter_0_8_msa(uint8_t *dst, uint8_t *src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
int16_t *sao_offset_val, int sao_left_class,
int width, int height);
void ff_hevc_sao_edge_filter_8_msa(uint8_t *dst, uint8_t *src,
ptrdiff_t stride_dst,
int16_t *sao_offset_val,
int eo, int width, int height);
void ff_hevc_idct_4x4_msa(int16_t *coeffs, int col_limit);
void ff_hevc_idct_8x8_msa(int16_t *coeffs, int col_limit);
void ff_hevc_idct_16x16_msa(int16_t *coeffs, int col_limit);
void ff_hevc_idct_32x32_msa(int16_t *coeffs, int col_limit);
void ff_hevc_idct_dc_4x4_msa(int16_t *coeffs);
void ff_hevc_idct_dc_8x8_msa(int16_t *coeffs);
void ff_hevc_idct_dc_16x16_msa(int16_t *coeffs);
void ff_hevc_idct_dc_32x32_msa(int16_t *coeffs);
void ff_hevc_addblk_4x4_msa(uint8_t *dst, int16_t *pi16Coeffs,
ptrdiff_t stride);
void ff_hevc_addblk_8x8_msa(uint8_t *dst, int16_t *pi16Coeffs,
ptrdiff_t stride);
void ff_hevc_addblk_16x16_msa(uint8_t *dst, int16_t *pi16Coeffs,
ptrdiff_t stride);
void ff_hevc_addblk_32x32_msa(uint8_t *dst, int16_t *pi16Coeffs,
ptrdiff_t stride);
void ff_hevc_idct_luma_4x4_msa(int16_t *pi16Coeffs);
/* Loongson optimization */
#define L_MC(PEL, DIR, WIDTH, TYPE) \
void ff_hevc_put_hevc_##PEL##_##DIR##WIDTH##_8_##TYPE(int16_t *dst, \
uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
L_MC(qpel, h, 4, mmi);
L_MC(qpel, h, 8, mmi);
L_MC(qpel, h, 12, mmi);
L_MC(qpel, h, 16, mmi);
L_MC(qpel, h, 24, mmi);
L_MC(qpel, h, 32, mmi);
L_MC(qpel, h, 48, mmi);
L_MC(qpel, h, 64, mmi);
L_MC(qpel, hv, 4, mmi);
L_MC(qpel, hv, 8, mmi);
L_MC(qpel, hv, 12, mmi);
L_MC(qpel, hv, 16, mmi);
L_MC(qpel, hv, 24, mmi);
L_MC(qpel, hv, 32, mmi);
L_MC(qpel, hv, 48, mmi);
L_MC(qpel, hv, 64, mmi);
#define L_BI_MC(PEL, DIR, WIDTH, TYPE) \
void ff_hevc_put_hevc_##PEL##_bi_##DIR##WIDTH##_8_##TYPE(uint8_t *dst, \
ptrdiff_t dst_stride, \
uint8_t *src, \
ptrdiff_t src_stride, \
int16_t *src2, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
L_BI_MC(pel, pixels, 8, mmi);
L_BI_MC(pel, pixels, 16, mmi);
L_BI_MC(pel, pixels, 24, mmi);
L_BI_MC(pel, pixels, 32, mmi);
L_BI_MC(pel, pixels, 48, mmi);
L_BI_MC(pel, pixels, 64, mmi);
L_BI_MC(qpel, hv, 4, mmi);
L_BI_MC(qpel, hv, 8, mmi);
L_BI_MC(qpel, hv, 12, mmi);
L_BI_MC(qpel, hv, 16, mmi);
L_BI_MC(qpel, hv, 24, mmi);
L_BI_MC(qpel, hv, 32, mmi);
L_BI_MC(qpel, hv, 48, mmi);
L_BI_MC(qpel, hv, 64, mmi);
L_BI_MC(qpel, h, 4, mmi);
L_BI_MC(qpel, h, 8, mmi);
L_BI_MC(qpel, h, 12, mmi);
L_BI_MC(qpel, h, 16, mmi);
L_BI_MC(qpel, h, 24, mmi);
L_BI_MC(qpel, h, 32, mmi);
L_BI_MC(qpel, h, 48, mmi);
L_BI_MC(qpel, h, 64, mmi);
L_BI_MC(epel, hv, 4, mmi);
L_BI_MC(epel, hv, 8, mmi);
L_BI_MC(epel, hv, 12, mmi);
L_BI_MC(epel, hv, 16, mmi);
L_BI_MC(epel, hv, 24, mmi);
L_BI_MC(epel, hv, 32, mmi);
#undef L_BI_MC
#define L_UNI_MC(PEL, DIR, WIDTH, TYPE) \
void ff_hevc_put_hevc_##PEL##_uni_##DIR##WIDTH##_8_##TYPE(uint8_t *dst, \
ptrdiff_t dst_stride, \
uint8_t *src, \
ptrdiff_t src_stride, \
int height, \
intptr_t mx, \
intptr_t my, \
int width)
L_UNI_MC(qpel, hv, 4, mmi);
L_UNI_MC(qpel, hv, 8, mmi);
L_UNI_MC(qpel, hv, 12, mmi);
L_UNI_MC(qpel, hv, 16, mmi);
L_UNI_MC(qpel, hv, 24, mmi);
L_UNI_MC(qpel, hv, 32, mmi);
L_UNI_MC(qpel, hv, 48, mmi);
L_UNI_MC(qpel, hv, 64, mmi);
#undef L_UNI_MC
#endif // #ifndef AVCODEC_MIPS_HEVCDSP_MIPS_H

1183
externals/ffmpeg/libavcodec/mips/hevcdsp_mmi.c vendored Executable file

File diff suppressed because it is too large Load Diff

4318
externals/ffmpeg/libavcodec/mips/hevcdsp_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavcodec/mips/hevcpred_mips.h"
#if HAVE_MSA
static av_cold void hevc_pred_init_msa(HEVCPredContext *c, const int bit_depth)
{
if (8 == bit_depth) {
c->intra_pred[2] = ff_intra_pred_8_16x16_msa;
c->intra_pred[3] = ff_intra_pred_8_32x32_msa;
c->pred_planar[0] = ff_hevc_intra_pred_planar_0_msa;
c->pred_planar[1] = ff_hevc_intra_pred_planar_1_msa;
c->pred_planar[2] = ff_hevc_intra_pred_planar_2_msa;
c->pred_planar[3] = ff_hevc_intra_pred_planar_3_msa;
c->pred_dc = ff_hevc_intra_pred_dc_msa;
c->pred_angular[0] = ff_pred_intra_pred_angular_0_msa;
c->pred_angular[1] = ff_pred_intra_pred_angular_1_msa;
c->pred_angular[2] = ff_pred_intra_pred_angular_2_msa;
c->pred_angular[3] = ff_pred_intra_pred_angular_3_msa;
}
}
#endif // #if HAVE_MSA
void ff_hevc_pred_init_mips(HEVCPredContext *c, const int bit_depth)
{
#if HAVE_MSA
hevc_pred_init_msa(c, bit_depth);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_HEVCPRED_MIPS_H
#define AVCODEC_MIPS_HEVCPRED_MIPS_H
#include "libavcodec/hevcpred.h"
void ff_hevc_intra_pred_planar_0_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride);
void ff_hevc_intra_pred_planar_1_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride);
void ff_hevc_intra_pred_planar_2_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride);
void ff_hevc_intra_pred_planar_3_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride);
void ff_hevc_intra_pred_dc_msa(uint8_t *dst, const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride, int log2, int c_idx);
void ff_pred_intra_pred_angular_0_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride, int c_idx, int mode);
void ff_pred_intra_pred_angular_1_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride, int c_idx, int mode);
void ff_pred_intra_pred_angular_2_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride, int c_idx, int mode);
void ff_pred_intra_pred_angular_3_msa(uint8_t *dst,
const uint8_t *src_top,
const uint8_t *src_left,
ptrdiff_t stride, int c_idx, int mode);
void ff_intra_pred_8_16x16_msa(struct HEVCContext *s, int x0, int y0, int c_idx);
void ff_intra_pred_8_32x32_msa(struct HEVCContext *s, int x0, int y0, int c_idx);
#endif // #ifndef AVCODEC_MIPS_HEVCPRED_MIPS_H

3077
externals/ffmpeg/libavcodec/mips/hevcpred_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
* Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../hpeldsp.h"
#include "libavcodec/mips/hpeldsp_mips.h"
#if HAVE_MSA
static void ff_hpeldsp_init_msa(HpelDSPContext *c, int flags)
{
c->put_pixels_tab[0][0] = ff_put_pixels16_msa;
c->put_pixels_tab[0][1] = ff_put_pixels16_x2_msa;
c->put_pixels_tab[0][2] = ff_put_pixels16_y2_msa;
c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_msa;
c->put_pixels_tab[1][0] = ff_put_pixels8_msa;
c->put_pixels_tab[1][1] = ff_put_pixels8_x2_msa;
c->put_pixels_tab[1][2] = ff_put_pixels8_y2_msa;
c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_msa;
c->put_pixels_tab[2][1] = ff_put_pixels4_x2_msa;
c->put_pixels_tab[2][2] = ff_put_pixels4_y2_msa;
c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_msa;
c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_msa;
c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_msa;
c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_msa;
c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_msa;
c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_msa;
c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_msa;
c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_msa;
c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_msa;
c->avg_pixels_tab[0][0] = ff_avg_pixels16_msa;
c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_msa;
c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_msa;
c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_msa;
c->avg_pixels_tab[1][0] = ff_avg_pixels8_msa;
c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_msa;
c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_msa;
c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_msa;
c->avg_pixels_tab[2][0] = ff_avg_pixels4_msa;
c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_msa;
c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_msa;
c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_msa;
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static void ff_hpeldsp_init_mmi(HpelDSPContext *c, int flags)
{
c->put_pixels_tab[0][0] = ff_put_pixels16_8_mmi;
c->put_pixels_tab[0][1] = ff_put_pixels16_x2_8_mmi;
c->put_pixels_tab[0][2] = ff_put_pixels16_y2_8_mmi;
c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_8_mmi;
c->put_pixels_tab[1][0] = ff_put_pixels8_8_mmi;
c->put_pixels_tab[1][1] = ff_put_pixels8_x2_8_mmi;
c->put_pixels_tab[1][2] = ff_put_pixels8_y2_8_mmi;
c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_8_mmi;
c->put_pixels_tab[2][0] = ff_put_pixels4_8_mmi;
c->put_pixels_tab[2][1] = ff_put_pixels4_x2_8_mmi;
c->put_pixels_tab[2][2] = ff_put_pixels4_y2_8_mmi;
c->put_pixels_tab[2][3] = ff_put_pixels4_xy2_8_mmi;
c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_8_mmi;
c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_8_mmi;
c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_8_mmi;
c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_8_mmi;
c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_8_mmi;
c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_8_mmi;
c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_8_mmi;
c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_8_mmi;
c->avg_pixels_tab[0][0] = ff_avg_pixels16_8_mmi;
c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_8_mmi;
c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_8_mmi;
c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_8_mmi;
c->avg_pixels_tab[1][0] = ff_avg_pixels8_8_mmi;
c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_8_mmi;
c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_8_mmi;
c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_8_mmi;
c->avg_pixels_tab[2][0] = ff_avg_pixels4_8_mmi;
c->avg_pixels_tab[2][1] = ff_avg_pixels4_x2_8_mmi;
c->avg_pixels_tab[2][2] = ff_avg_pixels4_y2_8_mmi;
c->avg_pixels_tab[2][3] = ff_avg_pixels4_xy2_8_mmi;
}
#endif // #if HAVE_MMI
void ff_hpeldsp_init_mips(HpelDSPContext *c, int flags)
{
#if HAVE_MMI
ff_hpeldsp_init_mmi(c, flags);
#endif // #if HAVE_MMI
#if HAVE_MSA
ff_hpeldsp_init_msa(c, flags);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
* Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_HPELDSP_MIPS_H
#define AVCODEC_MIPS_HPELDSP_MIPS_H
#include "libavcodec/bit_depth_template.c"
void ff_put_pixels16_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_x2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_y2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_xy2_msa(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_put_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_put_pixels4_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_avg_pixels16_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_avg_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_avg_pixels4_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_put_no_rnd_pixels16_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_put_no_rnd_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
int h);
void ff_put_pixels16_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_pixels4_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_put_no_rnd_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
void ff_avg_pixels4_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int32_t h);
#endif // #ifndef AVCODEC_MIPS_HPELDSP_MIPS_H

1117
externals/ffmpeg/libavcodec/mips/hpeldsp_mmi.c vendored Executable file

File diff suppressed because it is too large Load Diff

1516
externals/ffmpeg/libavcodec/mips/hpeldsp_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "idctdsp_mips.h"
#include "xvididct_mips.h"
#if HAVE_MSA
static av_cold void idctdsp_init_msa(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) &&
(avctx->bits_per_raw_sample != 10) &&
(avctx->bits_per_raw_sample != 12) &&
(avctx->idct_algo == FF_IDCT_AUTO)) {
c->idct_put = ff_simple_idct_put_msa;
c->idct_add = ff_simple_idct_add_msa;
c->idct = ff_simple_idct_msa;
c->perm_type = FF_IDCT_PERM_NONE;
}
c->put_pixels_clamped = ff_put_pixels_clamped_msa;
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_msa;
c->add_pixels_clamped = ff_add_pixels_clamped_msa;
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void idctdsp_init_mmi(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
if ((avctx->lowres != 1) && (avctx->lowres != 2) && (avctx->lowres != 3) &&
(avctx->bits_per_raw_sample != 10) &&
(avctx->bits_per_raw_sample != 12) &&
((avctx->idct_algo == FF_IDCT_AUTO) || (avctx->idct_algo == FF_IDCT_SIMPLE))) {
c->idct_put = ff_simple_idct_put_8_mmi;
c->idct_add = ff_simple_idct_add_8_mmi;
c->idct = ff_simple_idct_8_mmi;
c->perm_type = FF_IDCT_PERM_NONE;
}
c->put_pixels_clamped = ff_put_pixels_clamped_mmi;
c->add_pixels_clamped = ff_add_pixels_clamped_mmi;
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmi;
}
#endif /* HAVE_MMI */
av_cold void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
#if HAVE_MMI
idctdsp_init_mmi(c, avctx, high_bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
idctdsp_init_msa(c, avctx, high_bit_depth);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_IDCTDSP_MIPS_H
#define AVCODEC_MIPS_IDCTDSP_MIPS_H
#include "../mpegvideo.h"
void ff_put_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size);
void ff_put_signed_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size);
void ff_add_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size);
void ff_j_rev_dct_msa(int16_t *data);
void ff_jref_idct_put_msa(uint8_t *dest, ptrdiff_t stride, int16_t *block);
void ff_jref_idct_add_msa(uint8_t *dest, ptrdiff_t stride, int16_t *block);
void ff_simple_idct_msa(int16_t *block);
void ff_simple_idct_put_msa(uint8_t *dest, ptrdiff_t stride_dst, int16_t *block);
void ff_simple_idct_add_msa(uint8_t *dest, ptrdiff_t stride_dst, int16_t *block);
void ff_put_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size);
void ff_put_signed_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size);
void ff_add_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size);
void ff_simple_idct_8_mmi(int16_t *block);
void ff_simple_idct_put_8_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_simple_idct_add_8_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
#endif // #ifndef AVCODEC_MIPS_IDCTDSP_MIPS_H

193
externals/ffmpeg/libavcodec/mips/idctdsp_mmi.c vendored Executable file
View File

@@ -0,0 +1,193 @@
/*
* Loongson SIMD optimized idctdsp
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "idctdsp_mips.h"
#include "constants.h"
#include "libavutil/mips/mmiutils.h"
void ff_put_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size)
{
double ftmp[8];
__asm__ volatile (
MMI_LDC1(%[ftmp0], %[block], 0x00)
MMI_LDC1(%[ftmp1], %[block], 0x08)
MMI_LDC1(%[ftmp2], %[block], 0x10)
MMI_LDC1(%[ftmp3], %[block], 0x18)
MMI_LDC1(%[ftmp4], %[block], 0x20)
MMI_LDC1(%[ftmp5], %[block], 0x28)
MMI_LDC1(%[ftmp6], %[block], 0x30)
MMI_LDC1(%[ftmp7], %[block], 0x38)
"packushb %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"packushb %[ftmp2], %[ftmp2], %[ftmp3] \n\t"
"packushb %[ftmp4], %[ftmp4], %[ftmp5] \n\t"
"packushb %[ftmp6], %[ftmp6], %[ftmp7] \n\t"
MMI_SDC1(%[ftmp0], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp2], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp4], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp6], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_LDC1(%[ftmp0], %[block], 0x40)
MMI_LDC1(%[ftmp1], %[block], 0x48)
MMI_LDC1(%[ftmp2], %[block], 0x50)
MMI_LDC1(%[ftmp3], %[block], 0x58)
MMI_LDC1(%[ftmp4], %[block], 0x60)
MMI_LDC1(%[ftmp5], %[block], 0x68)
MMI_LDC1(%[ftmp6], %[block], 0x70)
MMI_LDC1(%[ftmp7], %[block], 0x78)
"packushb %[ftmp0], %[ftmp0], %[ftmp1] \n\t"
"packushb %[ftmp2], %[ftmp2], %[ftmp3] \n\t"
"packushb %[ftmp4], %[ftmp4], %[ftmp5] \n\t"
"packushb %[ftmp6], %[ftmp6], %[ftmp7] \n\t"
MMI_SDC1(%[ftmp0], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp2], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp4], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp6], %[pixels], 0x00)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[pixels]"+&r"(pixels)
: [line_size]"r"((mips_reg)line_size),
[block]"r"(block)
: "memory"
);
}
void ff_put_signed_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size)
{
double ftmp[5];
__asm__ volatile (
MMI_LDC1(%[ftmp1], %[block], 0x00)
MMI_LDC1(%[ftmp0], %[block], 0x08)
"packsshb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp2], %[block], 0x10)
MMI_LDC1(%[ftmp0], %[block], 0x18)
"packsshb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp3], %[block], 0x20)
MMI_LDC1(%[ftmp0], %[block], 0x28)
"packsshb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp4], %[block], 0x30)
MMI_LDC1(%[ftmp0], %[block], 0x38)
"packsshb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
"paddb %[ftmp1], %[ftmp1], %[ff_pb_80] \n\t"
"paddb %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t"
"paddb %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t"
"paddb %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t"
MMI_SDC1(%[ftmp1], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp2], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp3], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp4], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_LDC1(%[ftmp1], %[block], 0x40)
MMI_LDC1(%[ftmp0], %[block], 0x48)
"packsshb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp2], %[block], 0x50)
MMI_LDC1(%[ftmp0], %[block], 0x58)
"packsshb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp3], %[block], 0x60)
MMI_LDC1(%[ftmp0], %[block], 0x68)
"packsshb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp4], %[block], 0x70)
MMI_LDC1(%[ftmp0], %[block], 0x78)
"packsshb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
"paddb %[ftmp1], %[ftmp1], %[ff_pb_80] \n\t"
"paddb %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t"
"paddb %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t"
"paddb %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t"
MMI_SDC1(%[ftmp1], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp2], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp3], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp4], %[pixels], 0x00)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]),
[pixels]"+&r"(pixels)
: [block]"r"(block),
[line_size]"r"((mips_reg)line_size),
[ff_pb_80]"f"(ff_pb_80)
: "memory"
);
}
void ff_add_pixels_clamped_mmi(const int16_t *block,
uint8_t *av_restrict pixels, ptrdiff_t line_size)
{
double ftmp[9];
uint64_t tmp[1];
__asm__ volatile (
"li %[tmp0], 0x04 \n\t"
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"1: \n\t"
MMI_LDC1(%[ftmp5], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_LDC1(%[ftmp6], %[pixels], 0x00)
PTR_SUBU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_LDC1(%[ftmp1], %[block], 0x00)
MMI_LDC1(%[ftmp2], %[block], 0x08)
MMI_LDC1(%[ftmp3], %[block], 0x10)
MMI_LDC1(%[ftmp4], %[block], 0x18)
PTR_ADDIU "%[block], %[block], 0x20 \n\t"
"punpckhbh %[ftmp7], %[ftmp5], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
"punpckhbh %[ftmp8], %[ftmp6], %[ftmp0] \n\t"
"punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp7] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp6] \n\t"
"paddh %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"packushb %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
MMI_SDC1(%[ftmp1], %[pixels], 0x00)
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
MMI_SDC1(%[ftmp3], %[pixels], 0x00)
"addi %[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDU "%[pixels], %[pixels], %[line_size] \n\t"
"bnez %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [tmp0]"=&r"(tmp[0]),
[pixels]"+&r"(pixels), [block]"+&r"(block)
: [line_size]"r"((mips_reg)line_size)
: "memory"
);
}

146
externals/ffmpeg/libavcodec/mips/idctdsp_msa.c vendored Executable file
View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "idctdsp_mips.h"
static void put_pixels_clamped_msa(const int16_t *block, uint8_t *pixels,
int32_t stride)
{
uint64_t in0_d, in1_d, in2_d, in3_d, in4_d, in5_d, in6_d, in7_d;
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
CLIP_SH8_0_255(in0, in1, in2, in3, in4, in5, in6, in7);
PCKEV_B4_SH(in0, in0, in1, in1, in2, in2, in3, in3, in0, in1, in2, in3);
PCKEV_B4_SH(in4, in4, in5, in5, in6, in6, in7, in7, in4, in5, in6, in7);
in0_d = __msa_copy_u_d((v2i64) in0, 0);
in1_d = __msa_copy_u_d((v2i64) in1, 0);
in2_d = __msa_copy_u_d((v2i64) in2, 0);
in3_d = __msa_copy_u_d((v2i64) in3, 0);
in4_d = __msa_copy_u_d((v2i64) in4, 0);
in5_d = __msa_copy_u_d((v2i64) in5, 0);
in6_d = __msa_copy_u_d((v2i64) in6, 0);
in7_d = __msa_copy_u_d((v2i64) in7, 0);
SD4(in0_d, in1_d, in2_d, in3_d, pixels, stride);
pixels += 4 * stride;
SD4(in4_d, in5_d, in6_d, in7_d, pixels, stride);
}
static void put_signed_pixels_clamped_msa(const int16_t *block, uint8_t *pixels,
int32_t stride)
{
uint64_t in0_d, in1_d, in2_d, in3_d, in4_d, in5_d, in6_d, in7_d;
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
in0 += 128;
in1 += 128;
in2 += 128;
in3 += 128;
in4 += 128;
in5 += 128;
in6 += 128;
in7 += 128;
CLIP_SH8_0_255(in0, in1, in2, in3, in4, in5, in6, in7);
PCKEV_B4_SH(in0, in0, in1, in1, in2, in2, in3, in3, in0, in1, in2, in3);
PCKEV_B4_SH(in4, in4, in5, in5, in6, in6, in7, in7, in4, in5, in6, in7);
in0_d = __msa_copy_u_d((v2i64) in0, 0);
in1_d = __msa_copy_u_d((v2i64) in1, 0);
in2_d = __msa_copy_u_d((v2i64) in2, 0);
in3_d = __msa_copy_u_d((v2i64) in3, 0);
in4_d = __msa_copy_u_d((v2i64) in4, 0);
in5_d = __msa_copy_u_d((v2i64) in5, 0);
in6_d = __msa_copy_u_d((v2i64) in6, 0);
in7_d = __msa_copy_u_d((v2i64) in7, 0);
SD4(in0_d, in1_d, in2_d, in3_d, pixels, stride);
pixels += 4 * stride;
SD4(in4_d, in5_d, in6_d, in7_d, pixels, stride);
}
static void add_pixels_clamped_msa(const int16_t *block, uint8_t *pixels,
int32_t stride)
{
uint64_t in0_d, in1_d, in2_d, in3_d, in4_d, in5_d, in6_d, in7_d;
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v16u8 pix_in0, pix_in1, pix_in2, pix_in3;
v16u8 pix_in4, pix_in5, pix_in6, pix_in7;
v8u16 pix0, pix1, pix2, pix3, pix4, pix5, pix6, pix7;
v8i16 zero = { 0 };
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
LD_UB8(pixels, stride, pix_in0, pix_in1, pix_in2,
pix_in3, pix_in4, pix_in5, pix_in6, pix_in7);
ILVR_B4_UH(zero, pix_in0, zero, pix_in1, zero, pix_in2, zero, pix_in3,
pix0, pix1, pix2, pix3);
ILVR_B4_UH(zero, pix_in4, zero, pix_in5, zero, pix_in6, zero, pix_in7,
pix4, pix5, pix6, pix7);
in0 += (v8i16) pix0;
in1 += (v8i16) pix1;
in2 += (v8i16) pix2;
in3 += (v8i16) pix3;
in4 += (v8i16) pix4;
in5 += (v8i16) pix5;
in6 += (v8i16) pix6;
in7 += (v8i16) pix7;
CLIP_SH8_0_255(in0, in1, in2, in3, in4, in5, in6, in7);
PCKEV_B4_SH(in0, in0, in1, in1, in2, in2, in3, in3, in0, in1, in2, in3);
PCKEV_B4_SH(in4, in4, in5, in5, in6, in6, in7, in7, in4, in5, in6, in7);
in0_d = __msa_copy_u_d((v2i64) in0, 0);
in1_d = __msa_copy_u_d((v2i64) in1, 0);
in2_d = __msa_copy_u_d((v2i64) in2, 0);
in3_d = __msa_copy_u_d((v2i64) in3, 0);
in4_d = __msa_copy_u_d((v2i64) in4, 0);
in5_d = __msa_copy_u_d((v2i64) in5, 0);
in6_d = __msa_copy_u_d((v2i64) in6, 0);
in7_d = __msa_copy_u_d((v2i64) in7, 0);
SD4(in0_d, in1_d, in2_d, in3_d, pixels, stride);
pixels += 4 * stride;
SD4(in4_d, in5_d, in6_d, in7_d, pixels, stride);
}
void ff_put_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size)
{
put_pixels_clamped_msa(block, pixels, line_size);
}
void ff_put_signed_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size)
{
put_signed_pixels_clamped_msa(block, pixels, line_size);
}
void ff_add_pixels_clamped_msa(const int16_t *block,
uint8_t *av_restrict pixels,
ptrdiff_t line_size)
{
add_pixels_clamped_msa(block, pixels, line_size);
}

View File

@@ -0,0 +1,209 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Bojan Zivkovic (bojan@mips.com)
*
* IIR filter optimized for MIPS floating-point architecture
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/iirfilter.c
*/
#include "config.h"
#include "libavcodec/iirfilter.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
typedef struct FFIIRFilterCoeffs {
int order;
float gain;
int *cx;
float *cy;
} FFIIRFilterCoeffs;
typedef struct FFIIRFilterState {
float x[1];
} FFIIRFilterState;
static void iir_filter_flt_mips(const struct FFIIRFilterCoeffs *c,
struct FFIIRFilterState *s, int size,
const float *src, ptrdiff_t sstep, float *dst, ptrdiff_t dstep)
{
if (c->order == 2) {
int i;
const float *src0 = src;
float *dst0 = dst;
for (i = 0; i < size; i++) {
float in = *src0 * c->gain + s->x[0] * c->cy[0] + s->x[1] * c->cy[1];
*dst0 = s->x[0] + in + s->x[1] * c->cx[1];
s->x[0] = s->x[1];
s->x[1] = in;
src0 += sstep;
dst0 += dstep;
}
} else if (c->order == 4) {
int i;
const float *src0 = src;
float *dst0 = dst;
float four = 4.0;
float six = 6.0;
for (i = 0; i < size; i += 4) {
float in1, in2, in3, in4;
float res1, res2, res3, res4;
float *x = s->x;
float *cy = c->cy;
float gain = c->gain;
float src0_0 = src0[0 ];
float src0_1 = src0[sstep ];
float src0_2 = src0[2*sstep];
float src0_3 = src0[3*sstep];
__asm__ volatile (
"lwc1 $f0, 0(%[cy]) \n\t"
"lwc1 $f4, 0(%[x]) \n\t"
"lwc1 $f5, 4(%[x]) \n\t"
"lwc1 $f6, 8(%[x]) \n\t"
"lwc1 $f7, 12(%[x]) \n\t"
"mul.s %[in1], %[src0_0], %[gain] \n\t"
"mul.s %[in2], %[src0_1], %[gain] \n\t"
"mul.s %[in3], %[src0_2], %[gain] \n\t"
"mul.s %[in4], %[src0_3], %[gain] \n\t"
"lwc1 $f1, 4(%[cy]) \n\t"
"madd.s %[in1], %[in1], $f0, $f4 \n\t"
"madd.s %[in2], %[in2], $f0, $f5 \n\t"
"madd.s %[in3], %[in3], $f0, $f6 \n\t"
"madd.s %[in4], %[in4], $f0, $f7 \n\t"
"lwc1 $f2, 8(%[cy]) \n\t"
"madd.s %[in1], %[in1], $f1, $f5 \n\t"
"madd.s %[in2], %[in2], $f1, $f6 \n\t"
"madd.s %[in3], %[in3], $f1, $f7 \n\t"
"lwc1 $f3, 12(%[cy]) \n\t"
"add.s $f8, $f5, $f7 \n\t"
"madd.s %[in1], %[in1], $f2, $f6 \n\t"
"madd.s %[in2], %[in2], $f2, $f7 \n\t"
"mul.s $f9, $f6, %[six] \n\t"
"mul.s $f10, $f7, %[six] \n\t"
"madd.s %[in1], %[in1], $f3, $f7 \n\t"
"madd.s %[in2], %[in2], $f3, %[in1] \n\t"
"madd.s %[in3], %[in3], $f2, %[in1] \n\t"
"madd.s %[in4], %[in4], $f1, %[in1] \n\t"
"add.s %[res1], $f4, %[in1] \n\t"
"swc1 %[in1], 0(%[x]) \n\t"
"add.s $f0, $f6, %[in1] \n\t"
"madd.s %[in3], %[in3], $f3, %[in2] \n\t"
"madd.s %[in4], %[in4], $f2, %[in2] \n\t"
"add.s %[res2], $f5, %[in2] \n\t"
"madd.s %[res1], %[res1], $f8, %[four] \n\t"
"add.s $f8, $f7, %[in2] \n\t"
"swc1 %[in2], 4(%[x]) \n\t"
"madd.s %[in4], %[in4], $f3, %[in3] \n\t"
"add.s %[res3], $f6, %[in3] \n\t"
"add.s %[res1], %[res1], $f9 \n\t"
"madd.s %[res2], %[res2], $f0, %[four] \n\t"
"swc1 %[in3], 8(%[x]) \n\t"
"add.s %[res4], $f7, %[in4] \n\t"
"madd.s %[res3], %[res3], $f8, %[four] \n\t"
"swc1 %[in4], 12(%[x]) \n\t"
"add.s %[res2], %[res2], $f10 \n\t"
"add.s $f8, %[in1], %[in3] \n\t"
"madd.s %[res3], %[res3], %[in1], %[six] \n\t"
"madd.s %[res4], %[res4], $f8, %[four] \n\t"
"madd.s %[res4], %[res4], %[in2], %[six] \n\t"
: [in1]"=&f"(in1), [in2]"=&f"(in2),
[in3]"=&f"(in3), [in4]"=&f"(in4),
[res1]"=&f"(res1), [res2]"=&f"(res2),
[res3]"=&f"(res3), [res4]"=&f"(res4)
: [src0_0]"f"(src0_0), [src0_1]"f"(src0_1),
[src0_2]"f"(src0_2), [src0_3]"f"(src0_3),
[gain]"f"(gain), [x]"r"(x), [cy]"r"(cy),
[four]"f"(four), [six]"f"(six)
: "$f0", "$f1", "$f2", "$f3",
"$f4", "$f5", "$f6", "$f7",
"$f8", "$f9", "$f10",
"memory"
);
dst0[0 ] = res1;
dst0[sstep ] = res2;
dst0[2*sstep] = res3;
dst0[3*sstep] = res4;
src0 += 4*sstep;
dst0 += 4*dstep;
}
} else {
int i;
const float *src0 = src;
float *dst0 = dst;
for (i = 0; i < size; i++) {
int j;
float in, res;
in = *src0 * c->gain;
for(j = 0; j < c->order; j++)
in += c->cy[j] * s->x[j];
res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1];
for(j = 1; j < c->order >> 1; j++)
res += (s->x[j] + s->x[c->order - j]) * c->cx[j];
for(j = 0; j < c->order - 1; j++)
s->x[j] = s->x[j + 1];
*dst0 = res;
s->x[c->order - 1] = in;
src0 += sstep;
dst0 += dstep;
}
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_iir_filter_init_mips(FFIIRFilterContext *f) {
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
f->filter_flt = iir_filter_flt_mips;
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
}

113
externals/ffmpeg/libavcodec/mips/lsp_mips.h vendored Executable file
View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Nedeljko Babic (nbabic@mips.com)
*
* LSP routines for ACELP-based codecs optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/lsp.c
*/
#ifndef AVCODEC_MIPS_LSP_MIPS_H
#define AVCODEC_MIPS_LSP_MIPS_H
#if HAVE_MIPSFPU && HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
#include "libavutil/mips/asmdefs.h"
static av_always_inline void ff_lsp2polyf_mips(const double *lsp, double *f, int lp_half_order)
{
int i, j = 0;
double * p_fi = f;
double * p_f = 0;
f[0] = 1.0;
f[1] = -2 * lsp[0];
lsp -= 2;
for(i=2; i<=lp_half_order; i++)
{
double tmp, f_j_2, f_j_1, f_j;
double val = lsp[2*i];
__asm__ volatile(
"move %[p_f], %[p_fi] \n\t"
"add.d %[val], %[val], %[val] \n\t"
PTR_ADDIU "%[p_fi], 8 \n\t"
"ldc1 %[f_j_1], 0(%[p_f]) \n\t"
"ldc1 %[f_j], 8(%[p_f]) \n\t"
"neg.d %[val], %[val] \n\t"
"add.d %[tmp], %[f_j_1], %[f_j_1] \n\t"
"madd.d %[tmp], %[tmp], %[f_j], %[val] \n\t"
"addiu %[j], %[i], -2 \n\t"
"ldc1 %[f_j_2], -8(%[p_f]) \n\t"
"sdc1 %[tmp], 16(%[p_f]) \n\t"
"beqz %[j], ff_lsp2polyf_lp_j_end%= \n\t"
"ff_lsp2polyf_lp_j%=: \n\t"
"add.d %[tmp], %[f_j], %[f_j_2] \n\t"
"madd.d %[tmp], %[tmp], %[f_j_1], %[val] \n\t"
"mov.d %[f_j], %[f_j_1] \n\t"
"addiu %[j], -1 \n\t"
"mov.d %[f_j_1], %[f_j_2] \n\t"
"ldc1 %[f_j_2], -16(%[p_f]) \n\t"
"sdc1 %[tmp], 8(%[p_f]) \n\t"
PTR_ADDIU "%[p_f], -8 \n\t"
"bgtz %[j], ff_lsp2polyf_lp_j%= \n\t"
"ff_lsp2polyf_lp_j_end%=: \n\t"
: [f_j_2]"=&f"(f_j_2), [f_j_1]"=&f"(f_j_1), [val]"+f"(val),
[tmp]"=&f"(tmp), [f_j]"=&f"(f_j), [p_f]"+r"(p_f),
[j]"+r"(j), [p_fi]"+r"(p_fi)
: [i]"r"(i)
: "memory"
);
f[1] += val;
}
}
#define ff_lsp2polyf ff_lsp2polyf_mips
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM */
#endif /* AVCODEC_MIPS_LSP_MIPS_H */

67
externals/ffmpeg/libavcodec/mips/mathops.h vendored Executable file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_MATHOPS_H
#define AVCODEC_MIPS_MATHOPS_H
#include <stdint.h>
#include "config.h"
#include "libavutil/common.h"
#if HAVE_INLINE_ASM
#if HAVE_LOONGSON3
#define MULH MULH
static inline av_const int MULH(int a, int b)
{
int c;
__asm__ ("dmult %1, %2 \n\t"
"mflo %0 \n\t"
"dsrl %0, %0, 32 \n\t"
: "=r"(c)
: "r"(a),"r"(b)
: "hi", "lo");
return c;
}
#define mid_pred mid_pred
static inline av_const int mid_pred(int a, int b, int c)
{
int t = b;
__asm__ ("sgt $8, %1, %2 \n\t"
"movn %0, %1, $8 \n\t"
"movn %1, %2, $8 \n\t"
"sgt $8, %1, %3 \n\t"
"movz %1, %3, $8 \n\t"
"sgt $8, %0, %1 \n\t"
"movn %0, %1, $8 \n\t"
: "+&r"(t),"+&r"(a)
: "r"(b),"r"(c)
: "$8");
return t;
}
#endif /* HAVE_LOONGSON3 */
#endif /* HAVE_INLINE_ASM */
#endif /* AVCODEC_MIPS_MATHOPS_H */

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "me_cmp_mips.h"
#if HAVE_MSA
static av_cold void me_cmp_msa(MECmpContext *c, AVCodecContext *avctx)
{
#if BIT_DEPTH == 8
c->pix_abs[0][0] = ff_pix_abs16_msa;
c->pix_abs[0][1] = ff_pix_abs16_x2_msa;
c->pix_abs[0][2] = ff_pix_abs16_y2_msa;
c->pix_abs[0][3] = ff_pix_abs16_xy2_msa;
c->pix_abs[1][0] = ff_pix_abs8_msa;
c->pix_abs[1][1] = ff_pix_abs8_x2_msa;
c->pix_abs[1][2] = ff_pix_abs8_y2_msa;
c->pix_abs[1][3] = ff_pix_abs8_xy2_msa;
c->hadamard8_diff[0] = ff_hadamard8_diff16_msa;
c->hadamard8_diff[1] = ff_hadamard8_diff8x8_msa;
c->hadamard8_diff[4] = ff_hadamard8_intra16_msa;
c->hadamard8_diff[5] = ff_hadamard8_intra8x8_msa;
c->sad[0] = ff_pix_abs16_msa;
c->sad[1] = ff_pix_abs8_msa;
c->sse[0] = ff_sse16_msa;
c->sse[1] = ff_sse8_msa;
c->sse[2] = ff_sse4_msa;
#endif
}
#endif // #if HAVE_MSA
av_cold void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx)
{
#if HAVE_MSA
me_cmp_msa(c, avctx);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_ME_CMP_MIPS_H
#define AVCODEC_MIPS_ME_CMP_MIPS_H
#include "../mpegvideo.h"
#include "libavcodec/bit_depth_template.c"
int ff_hadamard8_diff8x8_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h);
int ff_hadamard8_intra8x8_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h);
int ff_hadamard8_diff16_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h);
int ff_hadamard8_intra16_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h);
int ff_pix_abs16_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs16_x2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs16_y2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs16_xy2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs8_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs8_x2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs8_y2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_pix_abs8_xy2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h);
int ff_sse16_msa(MpegEncContext *v, uint8_t *pu8Src, uint8_t *pu8Ref,
ptrdiff_t stride, int i32Height);
int ff_sse8_msa(MpegEncContext *v, uint8_t *pu8Src, uint8_t *pu8Ref,
ptrdiff_t stride, int i32Height);
int ff_sse4_msa(MpegEncContext *v, uint8_t *pu8Src, uint8_t *pu8Ref,
ptrdiff_t stride, int i32Height);
void ff_add_pixels8_msa(uint8_t *av_restrict pixels, int16_t *block,
ptrdiff_t stride);
#endif // #ifndef AVCODEC_MIPS_ME_CMP_MIPS_H

686
externals/ffmpeg/libavcodec/mips/me_cmp_msa.c vendored Executable file
View File

@@ -0,0 +1,686 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "me_cmp_mips.h"
static uint32_t sad_8width_msa(uint8_t *src, int32_t src_stride,
uint8_t *ref, int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, ref0, ref1, ref2, ref3;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3);
ref += (4 * ref_stride);
PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2,
src0, src1, ref0, ref1);
sad += SAD_UB2_UH(src0, src1, ref0, ref1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_16width_msa(uint8_t *src, int32_t src_stride,
uint8_t *ref, int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, ref0, ref1;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
LD_UB2(src, src_stride, src0, src1);
src += (2 * src_stride);
LD_UB2(ref, ref_stride, ref0, ref1);
ref += (2 * ref_stride);
sad += SAD_UB2_UH(src0, src1, ref0, ref1);
LD_UB2(src, src_stride, src0, src1);
src += (2 * src_stride);
LD_UB2(ref, ref_stride, ref0, ref1);
ref += (2 * ref_stride);
sad += SAD_UB2_UH(src0, src1, ref0, ref1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_horiz_bilinear_filter_8width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, comp0, comp1;
v16u8 ref0, ref1, ref2, ref3, ref4, ref5;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 3); ht_cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3);
ref += (4 * ref_stride);
PCKEV_D2_UB(src1, src0, src3, src2, src0, src1);
PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref4, ref5);
SLDI_B4_UB(ref0, ref0, ref1, ref1, ref2, ref2, ref3, ref3, 1,
ref0, ref1, ref2, ref3);
PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1);
AVER_UB2_UB(ref4, ref0, ref5, ref1, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3);
ref += (4 * ref_stride);
PCKEV_D2_UB(src1, src0, src3, src2, src0, src1);
PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref4, ref5);
SLDI_B4_UB(ref0, ref0, ref1, ref1, ref2, ref2, ref3, ref3, 1,
ref0, ref1, ref2, ref3);
PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1);
AVER_UB2_UB(ref4, ref0, ref5, ref1, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_horiz_bilinear_filter_16width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, comp0, comp1;
v16u8 ref00, ref10, ref20, ref30, ref01, ref11, ref21, ref31;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 3); ht_cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref00, ref10, ref20, ref30);
LD_UB4(ref + 1, ref_stride, ref01, ref11, ref21, ref31);
ref += (4 * ref_stride);
AVER_UB2_UB(ref01, ref00, ref11, ref10, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
AVER_UB2_UB(ref21, ref20, ref31, ref30, comp0, comp1);
sad += SAD_UB2_UH(src2, src3, comp0, comp1);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref00, ref10, ref20, ref30);
LD_UB4(ref + 1, ref_stride, ref01, ref11, ref21, ref31);
ref += (4 * ref_stride);
AVER_UB2_UB(ref01, ref00, ref11, ref10, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
AVER_UB2_UB(ref21, ref20, ref31, ref30, comp0, comp1);
sad += SAD_UB2_UH(src2, src3, comp0, comp1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_vert_bilinear_filter_8width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, comp0, comp1;
v16u8 ref0, ref1, ref2, ref3, ref4;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 3); ht_cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB5(ref, ref_stride, ref0, ref1, ref2, ref3, ref4);
ref += (4 * ref_stride);
PCKEV_D2_UB(src1, src0, src3, src2, src0, src1);
PCKEV_D2_UB(ref1, ref0, ref2, ref1, ref0, ref1);
PCKEV_D2_UB(ref3, ref2, ref4, ref3, ref2, ref3);
AVER_UB2_UB(ref1, ref0, ref3, ref2, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB5(ref, ref_stride, ref0, ref1, ref2, ref3, ref4);
ref += (4 * ref_stride);
PCKEV_D2_UB(src1, src0, src3, src2, src0, src1);
PCKEV_D2_UB(ref1, ref0, ref2, ref1, ref0, ref1);
PCKEV_D2_UB(ref3, ref2, ref4, ref3, ref2, ref3);
AVER_UB2_UB(ref1, ref0, ref3, ref2, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_vert_bilinear_filter_16width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, comp0, comp1;
v16u8 ref0, ref1, ref2, ref3, ref4;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 3); ht_cnt--;) {
LD_UB5(ref, ref_stride, ref4, ref0, ref1, ref2, ref3);
ref += (5 * ref_stride);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
AVER_UB2_UB(ref0, ref4, ref1, ref0, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
AVER_UB2_UB(ref2, ref1, ref3, ref2, comp0, comp1);
sad += SAD_UB2_UH(src2, src3, comp0, comp1);
ref4 = ref3;
LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3);
ref += (3 * ref_stride);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
AVER_UB2_UB(ref0, ref4, ref1, ref0, comp0, comp1);
sad += SAD_UB2_UH(src0, src1, comp0, comp1);
AVER_UB2_UB(ref2, ref1, ref3, ref2, comp0, comp1);
sad += SAD_UB2_UH(src2, src3, comp0, comp1);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_hv_bilinear_filter_8width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, temp0, temp1, diff;
v16u8 ref0, ref1, ref2, ref3, ref4;
v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 };
v8u16 comp0, comp1, comp2, comp3;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
LD_UB5(ref, ref_stride, ref4, ref0, ref1, ref2, ref3);
ref += (4 * ref_stride);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
PCKEV_D2_UB(src1, src0, src3, src2, src0, src1);
VSHF_B2_UB(ref4, ref4, ref0, ref0, mask, mask, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
comp0 += comp1;
comp0 = (v8u16) __msa_srari_h((v8i16) comp0, 2);
comp0 = (v8u16) __msa_pckev_b((v16i8) comp0, (v16i8) comp0);
temp0 = (v16u8) __msa_vshf_b(mask, (v16i8) ref1, (v16i8) ref1);
comp2 = __msa_hadd_u_h(temp0, temp0);
comp1 += comp2;
comp1 = (v8u16) __msa_srari_h((v8i16) comp1, 2);
comp1 = (v8u16) __msa_pckev_b((v16i8) comp1, (v16i8) comp1);
comp1 = (v8u16) __msa_pckev_d((v2i64) comp1, (v2i64) comp0);
diff = (v16u8) __msa_asub_u_b(src0, (v16u8) comp1);
sad += __msa_hadd_u_h(diff, diff);
temp1 = (v16u8) __msa_vshf_b(mask, (v16i8) ref2, (v16i8) ref2);
comp3 = __msa_hadd_u_h(temp1, temp1);
comp2 += comp3;
comp2 = (v8u16) __msa_srari_h((v8i16) comp2, 2);
comp2 = (v8u16) __msa_pckev_b((v16i8) comp2, (v16i8) comp2);
temp0 = (v16u8) __msa_vshf_b(mask, (v16i8) ref3, (v16i8) ref3);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp3 += comp0;
comp3 = (v8u16) __msa_srari_h((v8i16) comp3, 2);
comp3 = (v8u16) __msa_pckev_b((v16i8) comp3, (v16i8) comp3);
comp3 = (v8u16) __msa_pckev_d((v2i64) comp3, (v2i64) comp2);
diff = (v16u8) __msa_asub_u_b(src1, (v16u8) comp3);
sad += __msa_hadd_u_h(diff, diff);
}
return (HADD_UH_U32(sad));
}
static uint32_t sad_hv_bilinear_filter_16width_msa(uint8_t *src,
int32_t src_stride,
uint8_t *ref,
int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
v16u8 src0, src1, src2, src3, comp, diff;
v16u8 temp0, temp1, temp2, temp3;
v16u8 ref00, ref01, ref02, ref03, ref04, ref10, ref11, ref12, ref13, ref14;
v8u16 comp0, comp1, comp2, comp3;
v8u16 sad = { 0 };
for (ht_cnt = (height >> 3); ht_cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB5(ref, ref_stride, ref04, ref00, ref01, ref02, ref03);
LD_UB5(ref + 1, ref_stride, ref14, ref10, ref11, ref12, ref13);
ref += (5 * ref_stride);
ILVRL_B2_UB(ref14, ref04, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
ILVRL_B2_UB(ref10, ref00, temp2, temp3);
comp2 = __msa_hadd_u_h(temp2, temp2);
comp3 = __msa_hadd_u_h(temp3, temp3);
comp0 += comp2;
comp1 += comp3;
SRARI_H2_UH(comp0, comp1, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp1, (v16i8) comp0);
diff = __msa_asub_u_b(src0, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref11, ref01, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
comp2 += comp0;
comp3 += comp1;
SRARI_H2_UH(comp2, comp3, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp3, (v16i8) comp2);
diff = __msa_asub_u_b(src1, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref12, ref02, temp2, temp3);
comp2 = __msa_hadd_u_h(temp2, temp2);
comp3 = __msa_hadd_u_h(temp3, temp3);
comp0 += comp2;
comp1 += comp3;
SRARI_H2_UH(comp0, comp1, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp1, (v16i8) comp0);
diff = __msa_asub_u_b(src2, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref13, ref03, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
comp2 += comp0;
comp3 += comp1;
SRARI_H2_UH(comp2, comp3, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp3, (v16i8) comp2);
diff = __msa_asub_u_b(src3, comp);
sad += __msa_hadd_u_h(diff, diff);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
LD_UB4(ref, ref_stride, ref00, ref01, ref02, ref03);
LD_UB4(ref + 1, ref_stride, ref10, ref11, ref12, ref13);
ref += (3 * ref_stride);
ILVRL_B2_UB(ref10, ref00, temp2, temp3);
comp2 = __msa_hadd_u_h(temp2, temp2);
comp3 = __msa_hadd_u_h(temp3, temp3);
comp0 += comp2;
comp1 += comp3;
SRARI_H2_UH(comp0, comp1, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp1, (v16i8) comp0);
diff = __msa_asub_u_b(src0, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref11, ref01, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
comp2 += comp0;
comp3 += comp1;
SRARI_H2_UH(comp2, comp3, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp3, (v16i8) comp2);
diff = __msa_asub_u_b(src1, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref12, ref02, temp2, temp3);
comp2 = __msa_hadd_u_h(temp2, temp2);
comp3 = __msa_hadd_u_h(temp3, temp3);
comp0 += comp2;
comp1 += comp3;
SRARI_H2_UH(comp0, comp1, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp1, (v16i8) comp0);
diff = __msa_asub_u_b(src2, comp);
sad += __msa_hadd_u_h(diff, diff);
ILVRL_B2_UB(ref13, ref03, temp0, temp1);
comp0 = __msa_hadd_u_h(temp0, temp0);
comp1 = __msa_hadd_u_h(temp1, temp1);
comp2 += comp0;
comp3 += comp1;
SRARI_H2_UH(comp2, comp3, 2);
comp = (v16u8) __msa_pckev_b((v16i8) comp3, (v16i8) comp2);
diff = __msa_asub_u_b(src3, comp);
sad += __msa_hadd_u_h(diff, diff);
}
return (HADD_UH_U32(sad));
}
#define CALC_MSE_B(src, ref, var) \
{ \
v16u8 src_l0_m, src_l1_m; \
v8i16 res_l0_m, res_l1_m; \
\
ILVRL_B2_UB(src, ref, src_l0_m, src_l1_m); \
HSUB_UB2_SH(src_l0_m, src_l1_m, res_l0_m, res_l1_m); \
DPADD_SH2_SW(res_l0_m, res_l1_m, res_l0_m, res_l1_m, var, var); \
}
static uint32_t sse_4width_msa(uint8_t *src_ptr, int32_t src_stride,
uint8_t *ref_ptr, int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
uint32_t sse;
uint32_t src0, src1, src2, src3;
uint32_t ref0, ref1, ref2, ref3;
v16u8 src = { 0 };
v16u8 ref = { 0 };
v4i32 var = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
LW4(src_ptr, src_stride, src0, src1, src2, src3);
src_ptr += (4 * src_stride);
LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3);
ref_ptr += (4 * ref_stride);
INSERT_W4_UB(src0, src1, src2, src3, src);
INSERT_W4_UB(ref0, ref1, ref2, ref3, ref);
CALC_MSE_B(src, ref, var);
}
sse = HADD_SW_S32(var);
return sse;
}
static uint32_t sse_8width_msa(uint8_t *src_ptr, int32_t src_stride,
uint8_t *ref_ptr, int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
uint32_t sse;
v16u8 src0, src1, src2, src3;
v16u8 ref0, ref1, ref2, ref3;
v4i32 var = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
LD_UB4(src_ptr, src_stride, src0, src1, src2, src3);
src_ptr += (4 * src_stride);
LD_UB4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3);
ref_ptr += (4 * ref_stride);
PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2,
src0, src1, ref0, ref1);
CALC_MSE_B(src0, ref0, var);
CALC_MSE_B(src1, ref1, var);
}
sse = HADD_SW_S32(var);
return sse;
}
static uint32_t sse_16width_msa(uint8_t *src_ptr, int32_t src_stride,
uint8_t *ref_ptr, int32_t ref_stride,
int32_t height)
{
int32_t ht_cnt;
uint32_t sse;
v16u8 src, ref;
v4i32 var = { 0 };
for (ht_cnt = (height >> 2); ht_cnt--;) {
src = LD_UB(src_ptr);
src_ptr += src_stride;
ref = LD_UB(ref_ptr);
ref_ptr += ref_stride;
CALC_MSE_B(src, ref, var);
src = LD_UB(src_ptr);
src_ptr += src_stride;
ref = LD_UB(ref_ptr);
ref_ptr += ref_stride;
CALC_MSE_B(src, ref, var);
src = LD_UB(src_ptr);
src_ptr += src_stride;
ref = LD_UB(ref_ptr);
ref_ptr += ref_stride;
CALC_MSE_B(src, ref, var);
src = LD_UB(src_ptr);
src_ptr += src_stride;
ref = LD_UB(ref_ptr);
ref_ptr += ref_stride;
CALC_MSE_B(src, ref, var);
}
sse = HADD_SW_S32(var);
return sse;
}
static int32_t hadamard_diff_8x8_msa(uint8_t *src, int32_t src_stride,
uint8_t *ref, int32_t ref_stride)
{
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
v16u8 ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7;
v8u16 diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7;
v8u16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
v8i16 sum = { 0 };
v8i16 zero = { 0 };
LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7);
LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7);
ILVR_B8_UH(src0, ref0, src1, ref1, src2, ref2, src3, ref3,
src4, ref4, src5, ref5, src6, ref6, src7, ref7,
diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7);
HSUB_UB4_UH(diff0, diff1, diff2, diff3, diff0, diff1, diff2, diff3);
HSUB_UB4_UH(diff4, diff5, diff6, diff7, diff4, diff5, diff6, diff7);
TRANSPOSE8x8_UH_UH(diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7,
diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7);
BUTTERFLY_8(diff0, diff2, diff4, diff6, diff7, diff5, diff3, diff1,
temp0, temp2, temp4, temp6, temp7, temp5, temp3, temp1);
BUTTERFLY_8(temp0, temp1, temp4, temp5, temp7, temp6, temp3, temp2,
diff0, diff1, diff4, diff5, diff7, diff6, diff3, diff2);
BUTTERFLY_8(diff0, diff1, diff2, diff3, diff7, diff6, diff5, diff4,
temp0, temp1, temp2, temp3, temp7, temp6, temp5, temp4);
TRANSPOSE8x8_UH_UH(temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7,
temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7);
BUTTERFLY_8(temp0, temp2, temp4, temp6, temp7, temp5, temp3, temp1,
diff0, diff2, diff4, diff6, diff7, diff5, diff3, diff1);
BUTTERFLY_8(diff0, diff1, diff4, diff5, diff7, diff6, diff3, diff2,
temp0, temp1, temp4, temp5, temp7, temp6, temp3, temp2);
ADD4(temp0, temp4, temp1, temp5, temp2, temp6, temp3, temp7,
diff0, diff1, diff2, diff3);
sum = __msa_asub_s_h((v8i16) temp3, (v8i16) temp7);
sum += __msa_asub_s_h((v8i16) temp2, (v8i16) temp6);
sum += __msa_asub_s_h((v8i16) temp1, (v8i16) temp5);
sum += __msa_asub_s_h((v8i16) temp0, (v8i16) temp4);
sum += __msa_add_a_h((v8i16) diff0, zero);
sum += __msa_add_a_h((v8i16) diff1, zero);
sum += __msa_add_a_h((v8i16) diff2, zero);
sum += __msa_add_a_h((v8i16) diff3, zero);
return (HADD_UH_U32(sum));
}
static int32_t hadamard_intra_8x8_msa(uint8_t *src, int32_t src_stride,
uint8_t *ref, int32_t ref_stride)
{
int32_t sum_res = 0;
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
v8u16 diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7;
v8u16 temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
v8i16 sum = { 0 };
v16i8 zero = { 0 };
LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7);
TRANSPOSE8x8_UB_UB(src0, src1, src2, src3, src4, src5, src6, src7,
src0, src1, src2, src3, src4, src5, src6, src7);
ILVR_B8_UH(zero, src0, zero, src1, zero, src2, zero, src3,
zero, src4, zero, src5, zero, src6, zero, src7,
diff0, diff1, diff2, diff3, diff4, diff5, diff6, diff7);
BUTTERFLY_8(diff0, diff2, diff4, diff6, diff7, diff5, diff3, diff1,
temp0, temp2, temp4, temp6, temp7, temp5, temp3, temp1);
BUTTERFLY_8(temp0, temp1, temp4, temp5, temp7, temp6, temp3, temp2,
diff0, diff1, diff4, diff5, diff7, diff6, diff3, diff2);
BUTTERFLY_8(diff0, diff1, diff2, diff3, diff7, diff6, diff5, diff4,
temp0, temp1, temp2, temp3, temp7, temp6, temp5, temp4);
TRANSPOSE8x8_UH_UH(temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7,
temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7);
BUTTERFLY_8(temp0, temp2, temp4, temp6, temp7, temp5, temp3, temp1,
diff0, diff2, diff4, diff6, diff7, diff5, diff3, diff1);
BUTTERFLY_8(diff0, diff1, diff4, diff5, diff7, diff6, diff3, diff2,
temp0, temp1, temp4, temp5, temp7, temp6, temp3, temp2);
ADD4(temp0, temp4, temp1, temp5, temp2, temp6, temp3, temp7,
diff0, diff1, diff2, diff3);
sum = __msa_asub_s_h((v8i16) temp3, (v8i16) temp7);
sum += __msa_asub_s_h((v8i16) temp2, (v8i16) temp6);
sum += __msa_asub_s_h((v8i16) temp1, (v8i16) temp5);
sum += __msa_asub_s_h((v8i16) temp0, (v8i16) temp4);
sum += __msa_add_a_h((v8i16) diff0, (v8i16) zero);
sum += __msa_add_a_h((v8i16) diff1, (v8i16) zero);
sum += __msa_add_a_h((v8i16) diff2, (v8i16) zero);
sum += __msa_add_a_h((v8i16) diff3, (v8i16) zero);
sum_res = (HADD_UH_U32(sum));
sum_res -= abs(temp0[0] + temp4[0]);
return sum_res;
}
int ff_pix_abs16_msa(MpegEncContext *v, uint8_t *src, uint8_t *ref,
ptrdiff_t stride, int height)
{
return sad_16width_msa(src, stride, ref, stride, height);
}
int ff_pix_abs8_msa(MpegEncContext *v, uint8_t *src, uint8_t *ref,
ptrdiff_t stride, int height)
{
return sad_8width_msa(src, stride, ref, stride, height);
}
int ff_pix_abs16_x2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_horiz_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
}
int ff_pix_abs16_y2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_vert_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
}
int ff_pix_abs16_xy2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_hv_bilinear_filter_16width_msa(pix1, stride, pix2, stride, h);
}
int ff_pix_abs8_x2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_horiz_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
}
int ff_pix_abs8_y2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_vert_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
}
int ff_pix_abs8_xy2_msa(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
return sad_hv_bilinear_filter_8width_msa(pix1, stride, pix2, stride, h);
}
int ff_sse16_msa(MpegEncContext *v, uint8_t *src, uint8_t *ref,
ptrdiff_t stride, int height)
{
return sse_16width_msa(src, stride, ref, stride, height);
}
int ff_sse8_msa(MpegEncContext *v, uint8_t *src, uint8_t *ref,
ptrdiff_t stride, int height)
{
return sse_8width_msa(src, stride, ref, stride, height);
}
int ff_sse4_msa(MpegEncContext *v, uint8_t *src, uint8_t *ref,
ptrdiff_t stride, int height)
{
return sse_4width_msa(src, stride, ref, stride, height);
}
int ff_hadamard8_diff8x8_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h)
{
return hadamard_diff_8x8_msa(src, stride, dst, stride);
}
int ff_hadamard8_intra8x8_msa(MpegEncContext *s, uint8_t *dst, uint8_t *src,
ptrdiff_t stride, int h)
{
return hadamard_intra_8x8_msa(src, stride, dst, stride);
}
/* Hadamard Transform functions */
#define WRAPPER8_16_SQ(name8, name16) \
int name16(MpegEncContext *s, uint8_t *dst, uint8_t *src, \
ptrdiff_t stride, int h) \
{ \
int score = 0; \
score += name8(s, dst, src, stride, 8); \
score += name8(s, dst + 8, src + 8, stride, 8); \
if(h == 16) { \
dst += 8 * stride; \
src += 8 * stride; \
score +=name8(s, dst, src, stride, 8); \
score +=name8(s, dst + 8, src + 8, stride, 8); \
} \
return score; \
}
WRAPPER8_16_SQ(ff_hadamard8_diff8x8_msa, ff_hadamard8_diff16_msa);
WRAPPER8_16_SQ(ff_hadamard8_intra8x8_msa, ff_hadamard8_intra16_msa);

View File

@@ -0,0 +1,918 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Author: Bojan Zivkovic (bojan@mips.com)
*
* MPEG Audio decoder optimized for MIPS fixed-point architecture
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/mpegaudiodsp_template.c
*/
#include <string.h>
#include "libavutil/mips/asmdefs.h"
#include "libavcodec/mpegaudiodsp.h"
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void ff_mpadsp_apply_window_mips_fixed(int32_t *synth_buf, int32_t *window,
int *dither_state, int16_t *samples, ptrdiff_t incr)
{
register const int32_t *w, *w2, *p;
int j;
int16_t *samples2;
int w_asm, p_asm, w_asm1, p_asm1, w_asm2, p_asm2;
int w2_asm, w2_asm1, *p_temp1, *p_temp2;
int sum1 = 0;
int const min_asm = -32768, max_asm = 32767;
int temp1, temp2 = 0, temp3 = 0;
int64_t sum;
/* copy to avoid wrap */
memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
samples2 = samples + 31 * incr;
w = window;
w2 = window + 31;
sum = *dither_state;
p = synth_buf + 16;
p_temp1 = synth_buf + 16;
p_temp2 = synth_buf + 48;
temp1 = sum;
/**
* use of round_sample function from the original code is eliminated,
* changed with appropriate assembly instructions.
*/
__asm__ volatile (
"mthi $zero \n\t"
"mtlo %[temp1] \n\t"
"lw %[w_asm], 0(%[w]) \n\t"
"lw %[p_asm], 0(%[p]) \n\t"
"lw %[w_asm1], 64*4(%[w]) \n\t"
"lw %[p_asm1], 64*4(%[p]) \n\t"
"lw %[w_asm2], 128*4(%[w]) \n\t"
"lw %[p_asm2], 128*4(%[p]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"madd %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 192*4(%[w]) \n\t"
"lw %[p_asm], 192*4(%[p]) \n\t"
"lw %[w_asm1], 256*4(%[w]) \n\t"
"lw %[p_asm1], 256*4(%[p]) \n\t"
"lw %[w_asm2], 320*4(%[w]) \n\t"
"lw %[p_asm2], 320*4(%[p]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"madd %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 384*4(%[w]) \n\t"
"lw %[p_asm], 384*4(%[p]) \n\t"
"lw %[w_asm1], 448*4(%[w]) \n\t"
"lw %[p_asm1], 448*4(%[p]) \n\t"
"lw %[w_asm2], 32*4(%[w]) \n\t"
"lw %[p_asm2], 32*4(%[p]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"msub %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 96*4(%[w]) \n\t"
"lw %[p_asm], 96*4(%[p]) \n\t"
"lw %[w_asm1], 160*4(%[w]) \n\t"
"lw %[p_asm1], 160*4(%[p]) \n\t"
"lw %[w_asm2], 224*4(%[w]) \n\t"
"lw %[p_asm2], 224*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 288*4(%[w]) \n\t"
"lw %[p_asm], 288*4(%[p]) \n\t"
"lw %[w_asm1], 352*4(%[w]) \n\t"
"lw %[p_asm1], 352*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"lw %[w_asm], 480*4(%[w]) \n\t"
"lw %[p_asm], 480*4(%[p]) \n\t"
"lw %[w_asm2], 416*4(%[w]) \n\t"
"lw %[p_asm2], 416*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub %[w_asm2], %[p_asm2] \n\t"
/*round_sample function from the original code is eliminated,
* changed with appropriate assembly instructions
* code example:
"extr.w %[sum1],$ac0,24 \n\t"
"mflo %[temp3], $ac0 \n\t"
"and %[temp1], %[temp3], 0x00ffffff \n\t"
"slt %[temp2], %[sum1], %[min_asm] \n\t"
"movn %[sum1], %[min_asm],%[temp2] \n\t"
"slt %[temp2], %[max_asm],%[sum1] \n\t"
"movn %[sum1], %[max_asm],%[temp2] \n\t"
"sh %[sum1], 0(%[samples]) \n\t"
*/
"extr.w %[sum1], $ac0, 24 \n\t"
"mflo %[temp3] \n\t"
PTR_ADDIU "%[w], %[w], 4 \n\t"
"and %[temp1], %[temp3], 0x00ffffff \n\t"
"slt %[temp2], %[sum1], %[min_asm] \n\t"
"movn %[sum1], %[min_asm], %[temp2] \n\t"
"slt %[temp2], %[max_asm], %[sum1] \n\t"
"movn %[sum1], %[max_asm], %[temp2] \n\t"
"sh %[sum1], 0(%[samples]) \n\t"
: [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
[p_asm1] "=&r" (p_asm1), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
[w_asm2] "=&r" (w_asm2), [p_asm2] "=&r" (p_asm2),
[sum1] "+r" (sum1), [w] "+r" (w), [temp3] "+r" (temp3)
: [p] "r" (p), [samples] "r" (samples), [min_asm] "r" (min_asm),
[max_asm] "r" (max_asm)
: "memory", "hi","lo"
);
samples += incr;
/* we calculate two samples at the same time to avoid one memory
access per two sample */
for(j = 1; j < 16; j++) {
__asm__ volatile (
"mthi $0, $ac1 \n\t"
"mtlo $0, $ac1 \n\t"
"mthi $0 \n\t"
"mtlo %[temp1] \n\t"
PTR_ADDIU "%[p_temp1], %[p_temp1], 4 \n\t"
"lw %[w_asm], 0(%[w]) \n\t"
"lw %[p_asm], 0(%[p_temp1]) \n\t"
"lw %[w2_asm], 0(%[w2]) \n\t"
"lw %[w_asm1], 64*4(%[w]) \n\t"
"lw %[p_asm1], 64*4(%[p_temp1]) \n\t"
"lw %[w2_asm1], 64*4(%[w2]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 128*4(%[w]) \n\t"
"lw %[p_asm], 128*4(%[p_temp1]) \n\t"
"lw %[w2_asm], 128*4(%[w2]) \n\t"
"lw %[w_asm1], 192*4(%[w]) \n\t"
"lw %[p_asm1], 192*4(%[p_temp1]) \n\t"
"lw %[w2_asm1], 192*4(%[w2]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 256*4(%[w]) \n\t"
"lw %[p_asm], 256*4(%[p_temp1]) \n\t"
"lw %[w2_asm], 256*4(%[w2]) \n\t"
"lw %[w_asm1], 320*4(%[w]) \n\t"
"lw %[p_asm1], 320*4(%[p_temp1]) \n\t"
"lw %[w2_asm1], 320*4(%[w2]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 384*4(%[w]) \n\t"
"lw %[p_asm], 384*4(%[p_temp1]) \n\t"
"lw %[w2_asm], 384*4(%[w2]) \n\t"
"lw %[w_asm1], 448*4(%[w]) \n\t"
"lw %[p_asm1], 448*4(%[p_temp1]) \n\t"
"lw %[w2_asm1], 448*4(%[w2]) \n\t"
"madd %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"madd %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
PTR_ADDIU "%[p_temp2], %[p_temp2], -4 \n\t"
"lw %[w_asm], 32*4(%[w]) \n\t"
"lw %[p_asm], 0(%[p_temp2]) \n\t"
"lw %[w2_asm], 32*4(%[w2]) \n\t"
"lw %[w_asm1], 96*4(%[w]) \n\t"
"lw %[p_asm1], 64*4(%[p_temp2]) \n\t"
"lw %[w2_asm1], 96*4(%[w2]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 160*4(%[w]) \n\t"
"lw %[p_asm], 128*4(%[p_temp2]) \n\t"
"lw %[w2_asm], 160*4(%[w2]) \n\t"
"lw %[w_asm1], 224*4(%[w]) \n\t"
"lw %[p_asm1], 192*4(%[p_temp2]) \n\t"
"lw %[w2_asm1], 224*4(%[w2]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 288*4(%[w]) \n\t"
"lw %[p_asm], 256*4(%[p_temp2]) \n\t"
"lw %[w2_asm], 288*4(%[w2]) \n\t"
"lw %[w_asm1], 352*4(%[w]) \n\t"
"lw %[p_asm1], 320*4(%[p_temp2]) \n\t"
"lw %[w2_asm1], 352*4(%[w2]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
"lw %[w_asm], 416*4(%[w]) \n\t"
"lw %[p_asm], 384*4(%[p_temp2]) \n\t"
"lw %[w2_asm], 416*4(%[w2]) \n\t"
"lw %[w_asm1], 480*4(%[w]) \n\t"
"lw %[p_asm1], 448*4(%[p_temp2]) \n\t"
"lw %[w2_asm1], 480*4(%[w2]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub $ac1, %[w2_asm], %[p_asm] \n\t"
"msub $ac1, %[w2_asm1], %[p_asm1] \n\t"
PTR_ADDIU "%[w], %[w], 4 \n\t"
PTR_ADDIU "%[w2], %[w2], -4 \n\t"
"mflo %[temp2] \n\t"
"extr.w %[sum1], $ac0, 24 \n\t"
"li %[temp3], 1 \n\t"
"and %[temp1], %[temp2], 0x00ffffff \n\t"
"madd $ac1, %[temp1], %[temp3] \n\t"
"slt %[temp2], %[sum1], %[min_asm] \n\t"
"movn %[sum1], %[min_asm], %[temp2] \n\t"
"slt %[temp2], %[max_asm], %[sum1] \n\t"
"movn %[sum1], %[max_asm], %[temp2] \n\t"
"sh %[sum1], 0(%[samples]) \n\t"
"mflo %[temp3], $ac1 \n\t"
"extr.w %[sum1], $ac1, 24 \n\t"
"and %[temp1], %[temp3], 0x00ffffff \n\t"
"slt %[temp2], %[sum1], %[min_asm] \n\t"
"movn %[sum1], %[min_asm], %[temp2] \n\t"
"slt %[temp2], %[max_asm], %[sum1] \n\t"
"movn %[sum1], %[max_asm], %[temp2] \n\t"
"sh %[sum1], 0(%[samples2]) \n\t"
: [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
[p_asm1] "=&r" (p_asm1), [w2_asm1] "=&r" (w2_asm1),
[w2_asm] "=&r" (w2_asm), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
[p_temp1] "+r" (p_temp1), [p_temp2] "+r" (p_temp2), [sum1] "+r" (sum1),
[w] "+r" (w), [w2] "+r" (w2), [samples] "+r" (samples),
[samples2] "+r" (samples2), [temp3] "+r" (temp3)
: [min_asm] "r" (min_asm), [max_asm] "r" (max_asm)
: "memory", "hi", "lo", "$ac1hi", "$ac1lo"
);
samples += incr;
samples2 -= incr;
}
p = synth_buf + 32;
__asm__ volatile (
"mthi $0 \n\t"
"mtlo %[temp1] \n\t"
"lw %[w_asm], 32*4(%[w]) \n\t"
"lw %[p_asm], 0(%[p]) \n\t"
"lw %[w_asm1], 96*4(%[w]) \n\t"
"lw %[p_asm1], 64*4(%[p]) \n\t"
"lw %[w_asm2], 160*4(%[w]) \n\t"
"lw %[p_asm2], 128*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 224*4(%[w]) \n\t"
"lw %[p_asm], 192*4(%[p]) \n\t"
"lw %[w_asm1], 288*4(%[w]) \n\t"
"lw %[p_asm1], 256*4(%[p]) \n\t"
"lw %[w_asm2], 352*4(%[w]) \n\t"
"lw %[p_asm2], 320*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"msub %[w_asm2], %[p_asm2] \n\t"
"lw %[w_asm], 416*4(%[w]) \n\t"
"lw %[p_asm], 384*4(%[p]) \n\t"
"lw %[w_asm1], 480*4(%[w]) \n\t"
"lw %[p_asm1], 448*4(%[p]) \n\t"
"msub %[w_asm], %[p_asm] \n\t"
"msub %[w_asm1], %[p_asm1] \n\t"
"extr.w %[sum1], $ac0, 24 \n\t"
"mflo %[temp2] \n\t"
"and %[temp1], %[temp2], 0x00ffffff \n\t"
"slt %[temp2], %[sum1], %[min_asm] \n\t"
"movn %[sum1], %[min_asm], %[temp2] \n\t"
"slt %[temp2], %[max_asm], %[sum1] \n\t"
"movn %[sum1], %[max_asm], %[temp2] \n\t"
"sh %[sum1], 0(%[samples]) \n\t"
: [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
[p_asm1] "=&r" (p_asm1), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
[w_asm2] "=&r" (w_asm2), [p_asm2] "=&r" (p_asm2), [sum1] "+r" (sum1)
: [w] "r" (w), [p] "r" (p), [samples] "r" (samples), [min_asm] "r" (min_asm),
[max_asm] "r" (max_asm)
: "memory", "hi", "lo", "$ac1hi", "$ac1lo"
);
*dither_state= temp1;
}
static void imdct36_mips_fixed(int *out, int *buf, int *in, int *win)
{
int j;
int t0, t1, t2, t3, s0, s1, s2, s3;
int tmp[18], *tmp1, *in1;
/* temporary variables */
int temp_reg1, temp_reg2, temp_reg3, temp_reg4, temp_reg5, temp_reg6;
int t4, t5, t6, t8, t7;
/* values defined in macros and tables are
* eliminated - they are directly loaded in appropriate variables
*/
int const C_1 = 4229717092; /* cos(pi*1/18)*2 */
int const C_2 = 4035949074; /* cos(pi*2/18)*2 */
int const C_3 = 575416510; /* -cos(pi*3/18)*2 */
int const C_3A = 3719550786; /* cos(pi*3/18)*2 */
int const C_4 = 1004831466; /* -cos(pi*4/18)*2 */
int const C_5 = 1534215534; /* -cos(pi*5/18)*2 */
int const C_7 = -1468965330; /* -cos(pi*7/18)*2 */
int const C_8 = -745813244; /* -cos(pi*8/18)*2 */
/*
* instructions of the first two loops are reorganized and loops are unrolled,
* in order to eliminate unnecessary readings and writings in array
*/
__asm__ volatile (
"lw %[t1], 17*4(%[in]) \n\t"
"lw %[t2], 16*4(%[in]) \n\t"
"lw %[t3], 15*4(%[in]) \n\t"
"lw %[t4], 14*4(%[in]) \n\t"
"addu %[t1], %[t1], %[t2] \n\t"
"addu %[t2], %[t2], %[t3] \n\t"
"addu %[t3], %[t3], %[t4] \n\t"
"lw %[t5], 13*4(%[in]) \n\t"
"addu %[t1], %[t1], %[t3] \n\t"
"sw %[t2], 16*4(%[in]) \n\t"
"lw %[t6], 12*4(%[in]) \n\t"
"sw %[t1], 17*4(%[in]) \n\t"
"addu %[t4], %[t4], %[t5] \n\t"
"addu %[t5], %[t5], %[t6] \n\t"
"lw %[t7], 11*4(%[in]) \n\t"
"addu %[t3], %[t3], %[t5] \n\t"
"sw %[t4], 14*4(%[in]) \n\t"
"lw %[t8], 10*4(%[in]) \n\t"
"sw %[t3], 15*4(%[in]) \n\t"
"addu %[t6], %[t6], %[t7] \n\t"
"addu %[t7], %[t7], %[t8] \n\t"
"sw %[t6], 12*4(%[in]) \n\t"
"addu %[t5], %[t5], %[t7] \n\t"
"lw %[t1], 9*4(%[in]) \n\t"
"lw %[t2], 8*4(%[in]) \n\t"
"sw %[t5], 13*4(%[in]) \n\t"
"addu %[t8], %[t8], %[t1] \n\t"
"addu %[t1], %[t1], %[t2] \n\t"
"sw %[t8], 10*4(%[in]) \n\t"
"addu %[t7], %[t7], %[t1] \n\t"
"lw %[t3], 7*4(%[in]) \n\t"
"lw %[t4], 6*4(%[in]) \n\t"
"sw %[t7], 11*4(%[in]) \n\t"
"addu %[t2], %[t2], %[t3] \n\t"
"addu %[t3], %[t3], %[t4] \n\t"
"sw %[t2], 8*4(%[in]) \n\t"
"addu %[t1], %[t1], %[t3] \n\t"
"lw %[t5], 5*4(%[in]) \n\t"
"lw %[t6], 4*4(%[in]) \n\t"
"sw %[t1], 9*4(%[in]) \n\t"
"addu %[t4], %[t4], %[t5] \n\t"
"addu %[t5], %[t5], %[t6] \n\t"
"sw %[t4], 6*4(%[in]) \n\t"
"addu %[t3], %[t3], %[t5] \n\t"
"lw %[t7], 3*4(%[in]) \n\t"
"lw %[t8], 2*4(%[in]) \n\t"
"sw %[t3], 7*4(%[in]) \n\t"
"addu %[t6], %[t6], %[t7] \n\t"
"addu %[t7], %[t7], %[t8] \n\t"
"sw %[t6], 4*4(%[in]) \n\t"
"addu %[t5], %[t5], %[t7] \n\t"
"lw %[t1], 1*4(%[in]) \n\t"
"lw %[t2], 0*4(%[in]) \n\t"
"sw %[t5], 5*4(%[in]) \n\t"
"addu %[t8], %[t8], %[t1] \n\t"
"addu %[t1], %[t1], %[t2] \n\t"
"sw %[t8], 2*4(%[in]) \n\t"
"addu %[t7], %[t7], %[t1] \n\t"
"sw %[t7], 3*4(%[in]) \n\t"
"sw %[t1], 1*4(%[in]) \n\t"
: [in] "+r" (in), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3),
[t4] "=&r" (t4), [t5] "=&r" (t5), [t6] "=&r" (t6),
[t7] "=&r" (t7), [t8] "=&r" (t8)
:
: "memory"
);
for(j = 0; j < 2; j++) {
tmp1 = tmp + j;
in1 = in + j;
/**
* Original constants are multiplied by two in advanced
* for assembly optimization (e.g. C_2 = 2 * C2).
* That can lead to overflow in operations where they are used.
*
* Example of the solution:
*
* in original code:
* t0 = ((int64_t)(in1[2*2] + in1[2*4]) * (int64_t)(2*C2))>>32
*
* in assembly:
* C_2 = 2 * C2;
* .
* .
* "lw %[t7], 4*4(%[in1]) \n\t"
* "lw %[t8], 8*4(%[in1]) \n\t"
* "addu %[temp_reg2],%[t7], %[t8] \n\t"
* "multu %[C_2], %[temp_reg2] \n\t"
* "mfhi %[temp_reg1] \n\t"
* "sra %[temp_reg2],%[temp_reg2],31 \n\t"
* "move %[t0], $0 \n\t"
* "movn %[t0], %[C_2], %[temp_reg2] \n\t"
* "sub %[t0], %[temp_reg1],%[t0] \n\t"
*/
__asm__ volatile (
"lw %[t7], 4*4(%[in1]) \n\t"
"lw %[t8], 8*4(%[in1]) \n\t"
"lw %[t6], 16*4(%[in1]) \n\t"
"lw %[t4], 0*4(%[in1]) \n\t"
"addu %[temp_reg2], %[t7], %[t8] \n\t"
"addu %[t2], %[t6], %[t8] \n\t"
"multu %[C_2], %[temp_reg2] \n\t"
"lw %[t5], 12*4(%[in1]) \n\t"
"sub %[t2], %[t2], %[t7] \n\t"
"sub %[t1], %[t4], %[t5] \n\t"
"sra %[t3], %[t5], 1 \n\t"
"sra %[temp_reg1], %[t2], 1 \n\t"
"addu %[t3], %[t3], %[t4] \n\t"
"sub %[temp_reg1], %[t1], %[temp_reg1] \n\t"
"sra %[temp_reg2], %[temp_reg2], 31 \n\t"
"sw %[temp_reg1], 6*4(%[tmp1]) \n\t"
"move %[t0], $0 \n\t"
"movn %[t0], %[C_2], %[temp_reg2] \n\t"
"mfhi %[temp_reg1] \n\t"
"addu %[t1], %[t1], %[t2] \n\t"
"sw %[t1], 16*4(%[tmp1]) \n\t"
"sub %[temp_reg4], %[t8], %[t6] \n\t"
"add %[temp_reg2], %[t7], %[t6] \n\t"
"mult $ac1, %[C_8], %[temp_reg4] \n\t"
"multu $ac2, %[C_4], %[temp_reg2] \n\t"
"sub %[t0], %[temp_reg1], %[t0] \n\t"
"sra %[temp_reg1], %[temp_reg2], 31 \n\t"
"move %[t2], $0 \n\t"
"movn %[t2], %[C_4], %[temp_reg1] \n\t"
"mfhi %[t1], $ac1 \n\t"
"mfhi %[temp_reg1], $ac2 \n\t"
"lw %[t6], 10*4(%[in1]) \n\t"
"lw %[t8], 14*4(%[in1]) \n\t"
"lw %[t7], 2*4(%[in1]) \n\t"
"lw %[t4], 6*4(%[in1]) \n\t"
"sub %[temp_reg3], %[t3], %[t0] \n\t"
"add %[temp_reg4], %[t3], %[t0] \n\t"
"sub %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"add %[temp_reg4], %[temp_reg4], %[t1] \n\t"
"sub %[t2], %[temp_reg1], %[t2] \n\t"
"sw %[temp_reg4], 2*4(%[tmp1]) \n\t"
"sub %[temp_reg3], %[temp_reg3], %[t2] \n\t"
"add %[temp_reg1], %[t3], %[t2] \n\t"
"sw %[temp_reg3], 10*4(%[tmp1]) \n\t"
"sub %[temp_reg1], %[temp_reg1], %[t1] \n\t"
"addu %[temp_reg2], %[t6], %[t8] \n\t"
"sw %[temp_reg1], 14*4(%[tmp1]) \n\t"
"sub %[temp_reg2], %[temp_reg2], %[t7] \n\t"
"addu %[temp_reg3], %[t7], %[t6] \n\t"
"multu $ac3, %[C_3], %[temp_reg2] \n\t"
"multu %[C_1], %[temp_reg3] \n\t"
"sra %[temp_reg1], %[temp_reg2], 31 \n\t"
"move %[t1], $0 \n\t"
"sra %[temp_reg3], %[temp_reg3], 31 \n\t"
"movn %[t1], %[C_3], %[temp_reg1] \n\t"
"mfhi %[temp_reg1], $ac3 \n\t"
"mfhi %[temp_reg4] \n\t"
"move %[t2], $0 \n\t"
"movn %[t2], %[C_1], %[temp_reg3] \n\t"
"sub %[temp_reg3], %[t6], %[t8] \n\t"
"sub %[t2], %[temp_reg4], %[t2] \n\t"
"multu $ac1, %[C_7], %[temp_reg3] \n\t"
"sub %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"sra %[temp_reg4], %[temp_reg3], 31 \n\t"
"sub %[t1], %[temp_reg1], %[t1] \n\t"
"move %[t3], $0 \n\t"
"sw %[t1], 4*4(%[tmp1]) \n\t"
"movn %[t3], %[C_7], %[temp_reg4] \n\t"
"multu $ac2, %[C_3A], %[t4] \n\t"
"add %[temp_reg2], %[t7], %[t8] \n\t"
"move %[t1], $0 \n\t"
"mfhi %[temp_reg4], $ac1 \n\t"
"multu $ac3,%[C_5], %[temp_reg2] \n\t"
"move %[t0], $0 \n\t"
"sra %[temp_reg1], %[temp_reg2], 31 \n\t"
"movn %[t1],%[C_5], %[temp_reg1] \n\t"
"sub %[temp_reg4], %[temp_reg4], %[temp_reg3] \n\t"
"mfhi %[temp_reg1], $ac3 \n\t"
"sra %[temp_reg3], %[t4], 31 \n\t"
"movn %[t0], %[C_3A], %[temp_reg3] \n\t"
"mfhi %[temp_reg3], $ac2 \n\t"
"sub %[t3], %[temp_reg4], %[t3] \n\t"
"add %[temp_reg4], %[t3], %[t2] \n\t"
"sub %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"sub %[t1], %[temp_reg1], %[t1] \n\t"
"sub %[t0], %[temp_reg3], %[t0] \n\t"
"add %[temp_reg1], %[t2], %[t1] \n\t"
"add %[temp_reg4], %[temp_reg4], %[t0] \n\t"
"sub %[temp_reg2], %[t3], %[t1] \n\t"
"sw %[temp_reg4], 0*4(%[tmp1]) \n\t"
"sub %[temp_reg1], %[temp_reg1], %[t0] \n\t"
"sub %[temp_reg2], %[temp_reg2], %[t0] \n\t"
"sw %[temp_reg1], 12*4(%[tmp1]) \n\t"
"sw %[temp_reg2], 8*4(%[tmp1]) \n\t"
: [t7] "=&r" (t7), [temp_reg1] "=&r" (temp_reg1),
[temp_reg2] "=&r" (temp_reg2), [temp_reg4] "=&r" (temp_reg4),
[temp_reg3] "=&r" (temp_reg3), [t8] "=&r" (t8), [t0] "=&r" (t0),
[t4] "=&r" (t4), [t5] "=&r" (t5), [t6] "=&r"(t6), [t2] "=&r" (t2),
[t3] "=&r" (t3), [t1] "=&r" (t1)
: [C_2] "r" (C_2), [in1] "r" (in1), [tmp1] "r" (tmp1), [C_8] "r" (C_8),
[C_4] "r" (C_4), [C_3] "r" (C_3), [C_1] "r" (C_1), [C_7] "r" (C_7),
[C_3A] "r" (C_3A), [C_5] "r" (C_5)
: "memory", "hi", "lo", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo",
"$ac3hi", "$ac3lo"
);
}
/**
* loop is unrolled four times
*
* values defined in tables(icos36[] and icos36h[]) are not loaded from
* these tables - they are directly loaded in appropriate registers
*
*/
__asm__ volatile (
"lw %[t2], 1*4(%[tmp]) \n\t"
"lw %[t3], 3*4(%[tmp]) \n\t"
"lw %[t0], 0*4(%[tmp]) \n\t"
"lw %[t1], 2*4(%[tmp]) \n\t"
"addu %[temp_reg1], %[t3], %[t2] \n\t"
"li %[temp_reg2], 0x807D2B1E \n\t"
"move %[s1], $0 \n\t"
"multu %[temp_reg2], %[temp_reg1] \n\t"
"sra %[temp_reg1], %[temp_reg1], 31 \n\t"
"movn %[s1], %[temp_reg2], %[temp_reg1] \n\t"
"sub %[temp_reg3], %[t3], %[t2] \n\t"
"li %[temp_reg4], 0x2de5151 \n\t"
"mfhi %[temp_reg2] \n\t"
"addu %[s0], %[t1], %[t0] \n\t"
"lw %[temp_reg5], 9*4(%[win]) \n\t"
"mult $ac1, %[temp_reg4], %[temp_reg3] \n\t"
"lw %[temp_reg6], 4*9*4(%[buf]) \n\t"
"sub %[s2], %[t1], %[t0] \n\t"
"lw %[temp_reg3], 29*4(%[win]) \n\t"
"subu %[s1], %[temp_reg2], %[s1] \n\t"
"lw %[temp_reg4], 28*4(%[win]) \n\t"
"add %[t0], %[s0], %[s1] \n\t"
"extr.w %[s3], $ac1,23 \n\t"
"mult $ac2, %[t0], %[temp_reg3] \n\t"
"sub %[t1], %[s0], %[s1] \n\t"
"lw %[temp_reg1], 4*8*4(%[buf]) \n\t"
"mult %[t1], %[temp_reg5] \n\t"
"lw %[temp_reg2], 8*4(%[win]) \n\t"
"mfhi %[temp_reg3], $ac2 \n\t"
"mult $ac3, %[t0], %[temp_reg4] \n\t"
"add %[t0], %[s2], %[s3] \n\t"
"mfhi %[temp_reg5] \n\t"
"mult $ac1, %[t1], %[temp_reg2] \n\t"
"sub %[t1], %[s2], %[s3] \n\t"
"sw %[temp_reg3], 4*9*4(%[buf]) \n\t"
"mfhi %[temp_reg4], $ac3 \n\t"
"lw %[temp_reg3], 37*4(%[win]) \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"add %[temp_reg5], %[temp_reg5], %[temp_reg6] \n\t"
"lw %[temp_reg6], 17*4(%[win]) \n\t"
"sw %[temp_reg5], 32*9*4(%[out]) \n\t"
"sw %[temp_reg4], 4*8*4(%[buf]) \n\t"
"mult %[t1], %[temp_reg6] \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"lw %[temp_reg2], 0*4(%[win]) \n\t"
"lw %[temp_reg5], 4*17*4(%[buf]) \n\t"
"sw %[temp_reg1], 8*32*4(%[out]) \n\t"
"mfhi %[temp_reg6] \n\t"
"mult $ac1, %[t1], %[temp_reg2] \n\t"
"lw %[temp_reg4], 20*4(%[win]) \n\t"
"lw %[temp_reg1], 0(%[buf]) \n\t"
"mult $ac2, %[t0], %[temp_reg3] \n\t"
"mult %[t0], %[temp_reg4] \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"lw %[t0], 4*4(%[tmp]) \n\t"
"add %[temp_reg5], %[temp_reg5], %[temp_reg6] \n\t"
"mfhi %[temp_reg3], $ac2 \n\t"
"mfhi %[temp_reg4] \n\t"
"sw %[temp_reg5], 17*32*4(%[out]) \n\t"
"lw %[t1], 6*4(%[tmp]) \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"lw %[t2], 5*4(%[tmp]) \n\t"
"sw %[temp_reg1], 0*32*4(%[out]) \n\t"
"addu %[s0], %[t1], %[t0] \n\t"
"sw %[temp_reg3], 4*17*4(%[buf]) \n\t"
"lw %[t3], 7*4(%[tmp]) \n\t"
"sub %[s2], %[t1], %[t0] \n\t"
"sw %[temp_reg4], 0(%[buf]) \n\t"
"addu %[temp_reg5], %[t3], %[t2] \n\t"
"li %[temp_reg6], 0x8483EE0C \n\t"
"move %[s1], $0 \n\t"
"multu %[temp_reg6], %[temp_reg5] \n\t"
"sub %[temp_reg1], %[t3], %[t2] \n\t"
"li %[temp_reg2], 0xf746ea \n\t"
"sra %[temp_reg5], %[temp_reg5], 31 \n\t"
"mult $ac1, %[temp_reg2], %[temp_reg1] \n\t"
"movn %[s1], %[temp_reg6], %[temp_reg5] \n\t"
"mfhi %[temp_reg5] \n\t"
"lw %[temp_reg3], 10*4(%[win]) \n\t"
"lw %[temp_reg4], 4*10*4(%[buf]) \n\t"
"extr.w %[s3], $ac1, 23 \n\t"
"lw %[temp_reg1], 4*7*4(%[buf]) \n\t"
"lw %[temp_reg2], 7*4(%[win]) \n\t"
"lw %[temp_reg6], 30*4(%[win]) \n\t"
"subu %[s1], %[temp_reg5], %[s1] \n\t"
"sub %[t1], %[s0], %[s1] \n\t"
"add %[t0], %[s0], %[s1] \n\t"
"mult $ac2, %[t1], %[temp_reg3] \n\t"
"mult $ac3, %[t1], %[temp_reg2] \n\t"
"mult %[t0], %[temp_reg6] \n\t"
"lw %[temp_reg5], 27*4(%[win]) \n\t"
"mult $ac1, %[t0], %[temp_reg5] \n\t"
"mfhi %[temp_reg3], $ac2 \n\t"
"mfhi %[temp_reg2], $ac3 \n\t"
"mfhi %[temp_reg6] \n\t"
"add %[t0], %[s2], %[s3] \n\t"
"sub %[t1], %[s2], %[s3] \n\t"
"add %[temp_reg3], %[temp_reg3], %[temp_reg4] \n\t"
"lw %[temp_reg4], 16*4(%[win]) \n\t"
"mfhi %[temp_reg5], $ac1 \n\t"
"sw %[temp_reg3], 32*10*4(%[out]) \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"lw %[temp_reg3], 4*16*4(%[buf]) \n\t"
"sw %[temp_reg6], 4*10*4(%[buf]) \n\t"
"sw %[temp_reg1], 7*32*4(%[out]) \n\t"
"mult $ac2, %[t1], %[temp_reg4] \n\t"
"sw %[temp_reg5], 4*7*4(%[buf]) \n\t"
"lw %[temp_reg6], 1*4(%[win]) \n\t"
"lw %[temp_reg5], 4*1*4(%[buf]) \n\t"
"lw %[temp_reg1], 36*4(%[win]) \n\t"
"mult $ac3, %[t1], %[temp_reg6] \n\t"
"lw %[temp_reg2], 21*4(%[win]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"mult %[t0], %[temp_reg1] \n\t"
"mult $ac1, %[t0],%[temp_reg2] \n\t"
"lw %[t0], 8*4(%[tmp]) \n\t"
"mfhi %[temp_reg6], $ac3 \n\t"
"lw %[t1], 10*4(%[tmp]) \n\t"
"lw %[t3], 11*4(%[tmp]) \n\t"
"mfhi %[temp_reg1] \n\t"
"add %[temp_reg3], %[temp_reg3], %[temp_reg4] \n\t"
"lw %[t2], 9*4(%[tmp]) \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"add %[temp_reg5], %[temp_reg5], %[temp_reg6] \n\t"
"sw %[temp_reg3], 16*32*4(%[out]) \n\t"
"sw %[temp_reg5], 1*32*4(%[out]) \n\t"
"sw %[temp_reg1], 4*16*4(%[buf]) \n\t"
"addu %[temp_reg3], %[t3], %[t2] \n\t"
"li %[temp_reg4], 0x8D3B7CD6 \n\t"
"sw %[temp_reg2], 4*1*4(%[buf]) \n\t"
"multu %[temp_reg4],%[temp_reg3] \n\t"
"sra %[temp_reg3], %[temp_reg3], 31 \n\t"
"move %[s1], $0 \n\t"
"movn %[s1], %[temp_reg4], %[temp_reg3] \n\t"
"addu %[s0], %[t1], %[t0] \n\t"
"mfhi %[temp_reg3] \n\t"
"sub %[s2], %[t1], %[t0] \n\t"
"sub %[temp_reg5], %[t3], %[t2] \n\t"
"li %[temp_reg6], 0x976fd9 \n\t"
"lw %[temp_reg2], 11*4(%[win]) \n\t"
"lw %[temp_reg1], 4*11*4(%[buf]) \n\t"
"mult $ac1, %[temp_reg6], %[temp_reg5] \n\t"
"subu %[s1], %[temp_reg3], %[s1] \n\t"
"lw %[temp_reg5], 31*4(%[win]) \n\t"
"sub %[t1], %[s0], %[s1] \n\t"
"add %[t0], %[s0], %[s1] \n\t"
"mult $ac2, %[t1], %[temp_reg2] \n\t"
"mult %[t0], %[temp_reg5] \n\t"
"lw %[temp_reg4], 6*4(%[win]) \n\t"
"extr.w %[s3], $ac1, 23 \n\t"
"lw %[temp_reg3], 4*6*4(%[buf]) \n\t"
"mfhi %[temp_reg2], $ac2 \n\t"
"lw %[temp_reg6], 26*4(%[win]) \n\t"
"mfhi %[temp_reg5] \n\t"
"mult $ac3, %[t1], %[temp_reg4] \n\t"
"mult $ac1, %[t0], %[temp_reg6] \n\t"
"add %[t0], %[s2], %[s3] \n\t"
"sub %[t1], %[s2], %[s3] \n\t"
"add %[temp_reg2], %[temp_reg2], %[temp_reg1] \n\t"
"mfhi %[temp_reg4], $ac3 \n\t"
"mfhi %[temp_reg6], $ac1 \n\t"
"sw %[temp_reg5], 4*11*4(%[buf]) \n\t"
"sw %[temp_reg2], 32*11*4(%[out]) \n\t"
"lw %[temp_reg1], 4*15*4(%[buf]) \n\t"
"add %[temp_reg3], %[temp_reg3], %[temp_reg4] \n\t"
"lw %[temp_reg2], 15*4(%[win]) \n\t"
"sw %[temp_reg3], 6*32*4(%[out]) \n\t"
"sw %[temp_reg6], 4*6*4(%[buf]) \n\t"
"mult %[t1], %[temp_reg2] \n\t"
"lw %[temp_reg3], 2*4(%[win]) \n\t"
"lw %[temp_reg4], 4*2*4(%[buf]) \n\t"
"lw %[temp_reg5], 35*4(%[win]) \n\t"
"mult $ac1, %[t1], %[temp_reg3] \n\t"
"mfhi %[temp_reg2] \n\t"
"lw %[temp_reg6], 22*4(%[win]) \n\t"
"mult $ac2, %[t0], %[temp_reg5] \n\t"
"lw %[t1], 14*4(%[tmp]) \n\t"
"mult $ac3, %[t0], %[temp_reg6] \n\t"
"lw %[t0], 12*4(%[tmp]) \n\t"
"mfhi %[temp_reg3], $ac1 \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"mfhi %[temp_reg5], $ac2 \n\t"
"sw %[temp_reg1], 15*32*4(%[out]) \n\t"
"mfhi %[temp_reg6], $ac3 \n\t"
"lw %[t2], 13*4(%[tmp]) \n\t"
"lw %[t3], 15*4(%[tmp]) \n\t"
"add %[temp_reg4], %[temp_reg4], %[temp_reg3] \n\t"
"sw %[temp_reg5], 4*15*4(%[buf]) \n\t"
"addu %[temp_reg1], %[t3], %[t2] \n\t"
"li %[temp_reg2], 0x9C42577C \n\t"
"move %[s1], $0 \n\t"
"multu %[temp_reg2], %[temp_reg1] \n\t"
"sw %[temp_reg4], 2*32*4(%[out]) \n\t"
"sra %[temp_reg1], %[temp_reg1], 31 \n\t"
"movn %[s1], %[temp_reg2], %[temp_reg1] \n\t"
"sub %[temp_reg3], %[t3], %[t2] \n\t"
"li %[temp_reg4], 0x6f94a2 \n\t"
"mfhi %[temp_reg1] \n\t"
"addu %[s0], %[t1], %[t0] \n\t"
"sw %[temp_reg6], 4*2*4(%[buf]) \n\t"
"mult $ac1, %[temp_reg4], %[temp_reg3] \n\t"
"sub %[s2], %[t1], %[t0] \n\t"
"lw %[temp_reg5], 12*4(%[win]) \n\t"
"lw %[temp_reg6], 4*12*4(%[buf]) \n\t"
"subu %[s1], %[temp_reg1], %[s1] \n\t"
"sub %[t1], %[s0], %[s1] \n\t"
"lw %[temp_reg3], 32*4(%[win]) \n\t"
"mult $ac2, %[t1], %[temp_reg5] \n\t"
"add %[t0], %[s0], %[s1] \n\t"
"extr.w %[s3], $ac1, 23 \n\t"
"lw %[temp_reg2], 5*4(%[win]) \n\t"
"mult %[t0], %[temp_reg3] \n\t"
"mfhi %[temp_reg5], $ac2 \n\t"
"lw %[temp_reg4], 25*4(%[win]) \n\t"
"lw %[temp_reg1], 4*5*4(%[buf]) \n\t"
"mult $ac3, %[t1], %[temp_reg2] \n\t"
"mult $ac1, %[t0], %[temp_reg4] \n\t"
"mfhi %[temp_reg3] \n\t"
"add %[t0], %[s2], %[s3] \n\t"
"add %[temp_reg5], %[temp_reg5], %[temp_reg6] \n\t"
"mfhi %[temp_reg2], $ac3 \n\t"
"mfhi %[temp_reg4], $ac1 \n\t"
"sub %[t1], %[s2], %[s3] \n\t"
"sw %[temp_reg5], 32*12*4(%[out]) \n\t"
"sw %[temp_reg3], 4*12*4(%[buf]) \n\t"
"lw %[temp_reg6], 14*4(%[win]) \n\t"
"lw %[temp_reg5], 4*14*4(%[buf]) \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"sw %[temp_reg4], 4*5*4(%[buf]) \n\t"
"sw %[temp_reg1], 5*32*4(%[out]) \n\t"
"mult %[t1], %[temp_reg6] \n\t"
"lw %[temp_reg4], 34*4(%[win]) \n\t"
"lw %[temp_reg2], 3*4(%[win]) \n\t"
"lw %[temp_reg1], 4*3*4(%[buf]) \n\t"
"mult $ac2, %[t0], %[temp_reg4] \n\t"
"mfhi %[temp_reg6] \n\t"
"mult $ac1, %[t1], %[temp_reg2] \n\t"
"lw %[temp_reg3], 23*4(%[win]) \n\t"
"lw %[s0], 16*4(%[tmp]) \n\t"
"mfhi %[temp_reg4], $ac2 \n\t"
"lw %[t1], 17*4(%[tmp]) \n\t"
"mult $ac3, %[t0], %[temp_reg3] \n\t"
"move %[s1], $0 \n\t"
"add %[temp_reg5], %[temp_reg5], %[temp_reg6] \n\t"
"mfhi %[temp_reg2], $ac1 \n\t"
"sw %[temp_reg5], 14*32*4(%[out]) \n\t"
"sw %[temp_reg4], 4*14*4(%[buf]) \n\t"
"mfhi %[temp_reg3], $ac3 \n\t"
"li %[temp_reg5], 0xB504F334 \n\t"
"add %[temp_reg1], %[temp_reg1], %[temp_reg2] \n\t"
"multu %[temp_reg5], %[t1] \n\t"
"lw %[temp_reg2], 4*13*4(%[buf]) \n\t"
"sw %[temp_reg1], 3*32*4(%[out]) \n\t"
"sra %[t1], %[t1], 31 \n\t"
"mfhi %[temp_reg6] \n\t"
"movn %[s1], %[temp_reg5], %[t1] \n\t"
"sw %[temp_reg3], 4*3*4(%[buf]) \n\t"
"lw %[temp_reg1], 13*4(%[win]) \n\t"
"lw %[temp_reg4], 4*4*4(%[buf]) \n\t"
"lw %[temp_reg3], 4*4(%[win]) \n\t"
"lw %[temp_reg5], 33*4(%[win]) \n\t"
"subu %[s1], %[temp_reg6], %[s1] \n\t"
"lw %[temp_reg6], 24*4(%[win]) \n\t"
"sub %[t1], %[s0], %[s1] \n\t"
"add %[t0], %[s0], %[s1] \n\t"
"mult $ac1, %[t1], %[temp_reg1] \n\t"
"mult $ac2, %[t1], %[temp_reg3] \n\t"
"mult $ac3, %[t0], %[temp_reg5] \n\t"
"mult %[t0], %[temp_reg6] \n\t"
"mfhi %[temp_reg1], $ac1 \n\t"
"mfhi %[temp_reg3], $ac2 \n\t"
"mfhi %[temp_reg5], $ac3 \n\t"
"mfhi %[temp_reg6] \n\t"
"add %[temp_reg2], %[temp_reg2], %[temp_reg1] \n\t"
"add %[temp_reg4], %[temp_reg4], %[temp_reg3] \n\t"
"sw %[temp_reg2], 13*32*4(%[out]) \n\t"
"sw %[temp_reg4], 4*32*4(%[out]) \n\t"
"sw %[temp_reg5], 4*13*4(%[buf]) \n\t"
"sw %[temp_reg6], 4*4*4(%[buf]) \n\t"
: [t0] "=&r" (t0), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3),
[s0] "=&r" (s0), [s2] "=&r" (s2), [temp_reg1] "=&r" (temp_reg1),
[temp_reg2] "=&r" (temp_reg2), [s1] "=&r" (s1), [s3] "=&r" (s3),
[temp_reg3] "=&r" (temp_reg3), [temp_reg4] "=&r" (temp_reg4),
[temp_reg5] "=&r" (temp_reg5), [temp_reg6] "=&r" (temp_reg6),
[out] "+r" (out)
: [tmp] "r" (tmp), [win] "r" (win), [buf] "r" (buf)
: "memory", "hi", "lo", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo",
"$ac3hi", "$ac3lo"
);
}
static void ff_imdct36_blocks_mips_fixed(int *out, int *buf, int *in,
int count, int switch_point, int block_type)
{
int j;
for (j=0 ; j < count; j++) {
/* apply window & overlap with previous buffer */
/* select window */
int win_idx = (switch_point && j < 2) ? 0 : block_type;
int *win = ff_mdct_win_fixed[win_idx + (4 & -(j & 1))];
imdct36_mips_fixed(out, buf, in, win);
in += 18;
buf += ((j&3) != 3 ? 1 : (72-3));
out++;
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_INLINE_ASM */
void ff_mpadsp_init_mipsdsp(MPADSPContext *s)
{
#if HAVE_INLINE_ASM
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
s->apply_window_fixed = ff_mpadsp_apply_window_mips_fixed;
s->imdct36_blocks_fixed = ff_imdct36_blocks_mips_fixed;
#endif
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h263dsp_mips.h"
#include "mpegvideo_mips.h"
#if HAVE_MSA
static av_cold void dct_unquantize_init_msa(MpegEncContext *s)
{
s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_msa;
s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_msa;
if (!s->q_scale_type)
s->dct_unquantize_mpeg2_inter = ff_dct_unquantize_mpeg2_inter_msa;
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void dct_unquantize_init_mmi(MpegEncContext *s)
{
s->dct_unquantize_h263_intra = ff_dct_unquantize_h263_intra_mmi;
s->dct_unquantize_h263_inter = ff_dct_unquantize_h263_inter_mmi;
s->dct_unquantize_mpeg1_intra = ff_dct_unquantize_mpeg1_intra_mmi;
s->dct_unquantize_mpeg1_inter = ff_dct_unquantize_mpeg1_inter_mmi;
if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT))
if (!s->q_scale_type)
s->dct_unquantize_mpeg2_intra = ff_dct_unquantize_mpeg2_intra_mmi;
s->denoise_dct= ff_denoise_dct_mmi;
}
#endif /* HAVE_MMI */
av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
{
#if HAVE_MMI
dct_unquantize_init_mmi(s);
#endif /* HAVE_MMI */
#if HAVE_MSA
dct_unquantize_init_msa(s);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_MPEGVIDEO_MIPS_H
#define AVCODEC_MIPS_MPEGVIDEO_MIPS_H
#include "libavcodec/mpegvideo.h"
void ff_dct_unquantize_h263_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale);
void ff_dct_unquantize_h263_inter_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale);
void ff_dct_unquantize_mpeg1_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale);
void ff_dct_unquantize_mpeg1_inter_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale);
void ff_dct_unquantize_mpeg2_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale);
void ff_denoise_dct_mmi(MpegEncContext *s, int16_t *block);
#endif /* AVCODEC_MIPS_MPEGVIDEO_MIPS_H */

View File

@@ -0,0 +1,506 @@
/*
* Loongson SIMD optimized mpegvideo
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
* Zhang Shuangshuang <zhangshuangshuang@ict.ac.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mpegvideo_mips.h"
#include "libavutil/mips/mmiutils.h"
void ff_dct_unquantize_h263_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale)
{
int64_t level, qmul, qadd, nCoeffs;
double ftmp[6];
mips_reg addr[1];
DECLARE_VAR_ALL64;
qmul = qscale << 1;
av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
if (!s->h263_aic) {
if (n<4)
level = block[0] * s->y_dc_scale;
else
level = block[0] * s->c_dc_scale;
qadd = (qscale-1) | 1;
} else {
qadd = 0;
level = block[0];
}
if(s->ac_pred)
nCoeffs = 63;
else
nCoeffs = s->inter_scantable.raster_end[s->block_last_index[n]];
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"packsswh %[qmul], %[qmul], %[qmul] \n\t"
"packsswh %[qmul], %[qmul], %[qmul] \n\t"
"packsswh %[qadd], %[qadd], %[qadd] \n\t"
"packsswh %[qadd], %[qadd], %[qadd] \n\t"
"psubh %[ftmp0], %[ftmp0], %[qadd] \n\t"
"xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t"
".p2align 4 \n\t"
"1: \n\t"
PTR_ADDU "%[addr0], %[block], %[nCoeffs] \n\t"
MMI_LDC1(%[ftmp1], %[addr0], 0x00)
MMI_LDC1(%[ftmp2], %[addr0], 0x08)
"mov.d %[ftmp3], %[ftmp1] \n\t"
"mov.d %[ftmp4], %[ftmp2] \n\t"
"pmullh %[ftmp1], %[ftmp1], %[qmul] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[qmul] \n\t"
"pcmpgth %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"pcmpgth %[ftmp4], %[ftmp4], %[ftmp5] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp1] \n\t"
"xor %[ftmp4], %[ftmp4], %[ftmp2] \n\t"
"pcmpeqh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"pcmpeqh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"pandn %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"pandn %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
PTR_ADDIU "%[nCoeffs], %[nCoeffs], 0x10 \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
MMI_SDC1(%[ftmp2], %[addr0], 0x08)
"blez %[nCoeffs], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
RESTRICT_ASM_ALL64
[addr0]"=&r"(addr[0])
: [block]"r"((mips_reg)(block+nCoeffs)),
[nCoeffs]"r"((mips_reg)(2*(-nCoeffs))),
[qmul]"f"(qmul), [qadd]"f"(qadd)
: "memory"
);
block[0] = level;
}
void ff_dct_unquantize_h263_inter_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale)
{
int64_t qmul, qadd, nCoeffs;
double ftmp[6];
mips_reg addr[1];
DECLARE_VAR_ALL64;
qmul = qscale << 1;
qadd = (qscale - 1) | 1;
av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
nCoeffs = s->inter_scantable.raster_end[s->block_last_index[n]];
__asm__ volatile (
"packsswh %[qmul], %[qmul], %[qmul] \n\t"
"packsswh %[qmul], %[qmul], %[qmul] \n\t"
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"packsswh %[qadd], %[qadd], %[qadd] \n\t"
"packsswh %[qadd], %[qadd], %[qadd] \n\t"
"psubh %[ftmp0], %[ftmp0], %[qadd] \n\t"
"xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t"
".p2align 4 \n\t"
"1: \n\t"
PTR_ADDU "%[addr0], %[block], %[nCoeffs] \n\t"
MMI_LDC1(%[ftmp1], %[addr0], 0x00)
MMI_LDC1(%[ftmp2], %[addr0], 0x08)
"mov.d %[ftmp3], %[ftmp1] \n\t"
"mov.d %[ftmp4], %[ftmp2] \n\t"
"pmullh %[ftmp1], %[ftmp1], %[qmul] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[qmul] \n\t"
"pcmpgth %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"pcmpgth %[ftmp4], %[ftmp4], %[ftmp5] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"paddh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp1] \n\t"
"xor %[ftmp4], %[ftmp4], %[ftmp2] \n\t"
"pcmpeqh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"pcmpeqh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"pandn %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"pandn %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
PTR_ADDIU "%[nCoeffs], %[nCoeffs], 0x10 \n\t"
MMI_SDC1(%[ftmp1], %[addr0], 0x00)
MMI_SDC1(%[ftmp2], %[addr0], 0x08)
"blez %[nCoeffs], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
RESTRICT_ASM_ALL64
[addr0]"=&r"(addr[0])
: [block]"r"((mips_reg)(block+nCoeffs)),
[nCoeffs]"r"((mips_reg)(2*(-nCoeffs))),
[qmul]"f"(qmul), [qadd]"f"(qadd)
: "memory"
);
}
void ff_dct_unquantize_mpeg1_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale)
{
int64_t nCoeffs;
const uint16_t *quant_matrix;
int block0;
double ftmp[10];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
av_assert2(s->block_last_index[n]>=0);
nCoeffs = s->intra_scantable.raster_end[s->block_last_index[n]] + 1;
if (n<4)
block0 = block[0] * s->y_dc_scale;
else
block0 = block[0] * s->c_dc_scale;
/* XXX: only mpeg1 */
quant_matrix = s->intra_matrix;
__asm__ volatile (
"dli %[tmp0], 0x0f \n\t"
"pcmpeqh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"dmtc1 %[qscale], %[ftmp1] \n\t"
"psrlh %[ftmp0], %[ftmp0], %[ftmp4] \n\t"
"packsswh %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
"packsswh %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
"or %[addr0], %[nCoeffs], $0 \n\t"
".p2align 4 \n\t"
"1: \n\t"
MMI_LDXC1(%[ftmp2], %[addr0], %[block], 0x00)
MMI_LDXC1(%[ftmp3], %[addr0], %[block], 0x08)
"mov.d %[ftmp4], %[ftmp2] \n\t"
"mov.d %[ftmp5], %[ftmp3] \n\t"
MMI_LDXC1(%[ftmp6], %[addr0], %[quant], 0x00)
MMI_LDXC1(%[ftmp7], %[addr0], %[quant], 0x08)
"pmullh %[ftmp6], %[ftmp6], %[ftmp1] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t"
"xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t"
"pcmpgth %[ftmp8], %[ftmp8], %[ftmp2] \n\t"
"pcmpgth %[ftmp9], %[ftmp9], %[ftmp3] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
"xor %[ftmp6], %[ftmp6], %[ftmp6] \n\t"
"xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t"
"pcmpeqh %[ftmp6], %[ftmp6], %[ftmp4] \n\t"
"dli %[tmp0], 0x03 \n\t"
"pcmpeqh %[ftmp7], %[ftmp7], %[ftmp5] \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"psrah %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"or %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"or %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"pandn %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
"pandn %[ftmp7], %[ftmp7], %[ftmp3] \n\t"
MMI_SDXC1(%[ftmp6], %[addr0], %[block], 0x00)
MMI_SDXC1(%[ftmp7], %[addr0], %[block], 0x08)
PTR_ADDIU "%[addr0], %[addr0], 0x10 \n\t"
"bltz %[addr0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[addr0]"=&r"(addr[0])
: [block]"r"((mips_reg)(block+nCoeffs)),
[quant]"r"((mips_reg)(quant_matrix+nCoeffs)),
[nCoeffs]"r"((mips_reg)(2*(-nCoeffs))),
[qscale]"r"(qscale)
: "memory"
);
block[0] = block0;
}
void ff_dct_unquantize_mpeg1_inter_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale)
{
int64_t nCoeffs;
const uint16_t *quant_matrix;
double ftmp[10];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
av_assert2(s->block_last_index[n] >= 0);
nCoeffs = s->intra_scantable.raster_end[s->block_last_index[n]] + 1;
quant_matrix = s->inter_matrix;
__asm__ volatile (
"dli %[tmp0], 0x0f \n\t"
"pcmpeqh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"dmtc1 %[qscale], %[ftmp1] \n\t"
"psrlh %[ftmp0], %[ftmp0], %[ftmp4] \n\t"
"packsswh %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
"packsswh %[ftmp1], %[ftmp1], %[ftmp1] \n\t"
"or %[addr0], %[nCoeffs], $0 \n\t"
".p2align 4 \n\t"
"1: \n\t"
MMI_LDXC1(%[ftmp2], %[addr0], %[block], 0x00)
MMI_LDXC1(%[ftmp3], %[addr0], %[block], 0x08)
"mov.d %[ftmp4], %[ftmp2] \n\t"
"mov.d %[ftmp5], %[ftmp3] \n\t"
MMI_LDXC1(%[ftmp6], %[addr0], %[quant], 0x00)
MMI_LDXC1(%[ftmp7], %[addr0], %[quant], 0x08)
"pmullh %[ftmp6], %[ftmp6], %[ftmp1] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t"
"xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t"
"pcmpgth %[ftmp8], %[ftmp8], %[ftmp2] \n\t"
"pcmpgth %[ftmp9], %[ftmp9], %[ftmp3] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp2] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp3] \n\t"
"paddh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"paddh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
"pmullh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
"xor %[ftmp6], %[ftmp6], %[ftmp6] \n\t"
"xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t"
"pcmpeqh %[ftmp6], %[ftmp6], %[ftmp4] \n\t"
"dli %[tmp0], 0x04 \n\t"
"pcmpeqh %[ftmp7], %[ftmp7], %[ftmp5] \n\t"
"dmtc1 %[tmp0], %[ftmp4] \n\t"
"psrah %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"or %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
"or %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
"pandn %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
"pandn %[ftmp7], %[ftmp7], %[ftmp3] \n\t"
MMI_SDXC1(%[ftmp6], %[addr0], %[block], 0x00)
MMI_SDXC1(%[ftmp7], %[addr0], %[block], 0x08)
PTR_ADDIU "%[addr0], %[addr0], 0x10 \n\t"
"bltz %[addr0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[addr0]"=&r"(addr[0])
: [block]"r"((mips_reg)(block+nCoeffs)),
[quant]"r"((mips_reg)(quant_matrix+nCoeffs)),
[nCoeffs]"r"((mips_reg)(2*(-nCoeffs))),
[qscale]"r"(qscale)
: "memory"
);
}
void ff_dct_unquantize_mpeg2_intra_mmi(MpegEncContext *s, int16_t *block,
int n, int qscale)
{
uint64_t nCoeffs;
const uint16_t *quant_matrix;
int block0;
double ftmp[10];
uint64_t tmp[1];
mips_reg addr[1];
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
assert(s->block_last_index[n]>=0);
if (s->alternate_scan)
nCoeffs = 63;
else
nCoeffs = s->intra_scantable.raster_end[s->block_last_index[n]];
if (n < 4)
block0 = block[0] * s->y_dc_scale;
else
block0 = block[0] * s->c_dc_scale;
quant_matrix = s->intra_matrix;
__asm__ volatile (
"dli %[tmp0], 0x0f \n\t"
"pcmpeqh %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"mtc1 %[tmp0], %[ftmp3] \n\t"
"mtc1 %[qscale], %[ftmp9] \n\t"
"psrlh %[ftmp0], %[ftmp0], %[ftmp3] \n\t"
"packsswh %[ftmp9], %[ftmp9], %[ftmp9] \n\t"
"packsswh %[ftmp9], %[ftmp9], %[ftmp9] \n\t"
"or %[addr0], %[nCoeffs], $0 \n\t"
".p2align 4 \n\t"
"1: \n\t"
MMI_LDXC1(%[ftmp1], %[addr0], %[block], 0x00)
MMI_LDXC1(%[ftmp2], %[addr0], %[block], 0x08)
"mov.d %[ftmp3], %[ftmp1] \n\t"
"mov.d %[ftmp4], %[ftmp2] \n\t"
MMI_LDXC1(%[ftmp5], %[addr0], %[quant], 0x00)
MMI_LDXC1(%[ftmp6], %[addr0], %[quant], 0x08)
"pmullh %[ftmp5], %[ftmp5], %[ftmp9] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[ftmp9] \n\t"
"xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t"
"xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t"
"pcmpgth %[ftmp7], %[ftmp7], %[ftmp1] \n\t"
"pcmpgth %[ftmp8], %[ftmp8], %[ftmp2] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"pmullh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
"pmullh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
"xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t"
"xor %[ftmp6], %[ftmp6], %[ftmp6] \n\t"
"pcmpeqh %[ftmp5], %[ftmp5], %[ftmp3] \n\t"
"dli %[tmp0], 0x03 \n\t"
"pcmpeqh %[ftmp6] , %[ftmp6], %[ftmp4] \n\t"
"mtc1 %[tmp0], %[ftmp3] \n\t"
"psrah %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
"psrah %[ftmp2], %[ftmp2], %[ftmp3] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"xor %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"psubh %[ftmp1], %[ftmp1], %[ftmp7] \n\t"
"psubh %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"pandn %[ftmp5], %[ftmp5], %[ftmp1] \n\t"
"pandn %[ftmp6], %[ftmp6], %[ftmp2] \n\t"
MMI_SDXC1(%[ftmp5], %[addr0], %[block], 0x00)
MMI_SDXC1(%[ftmp6], %[addr0], %[block], 0x08)
PTR_ADDIU "%[addr0], %[addr0], 0x10 \n\t"
"blez %[addr0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
[ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[addr0]"=&r"(addr[0])
: [block]"r"((mips_reg)(block+nCoeffs)),
[quant]"r"((mips_reg)(quant_matrix+nCoeffs)),
[nCoeffs]"r"((mips_reg)(2*(-nCoeffs))),
[qscale]"r"(qscale)
: "memory"
);
block[0]= block0;
}
void ff_denoise_dct_mmi(MpegEncContext *s, int16_t *block)
{
const int intra = s->mb_intra;
int *sum = s->dct_error_sum[intra];
uint16_t *offset = s->dct_offset[intra];
double ftmp[8];
mips_reg addr[1];
DECLARE_VAR_ALL64;
s->dct_count[intra]++;
__asm__ volatile(
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"1: \n\t"
MMI_LDC1(%[ftmp1], %[block], 0x00)
"xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp3], %[block], 0x08)
"xor %[ftmp4], %[ftmp4], %[ftmp4] \n\t"
"pcmpgth %[ftmp2], %[ftmp2], %[ftmp1] \n\t"
"pcmpgth %[ftmp4], %[ftmp4], %[ftmp3] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psubh %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
MMI_LDC1(%[ftmp6], %[offset], 0x00)
"mov.d %[ftmp5], %[ftmp1] \n\t"
"psubush %[ftmp1], %[ftmp1], %[ftmp6] \n\t"
MMI_LDC1(%[ftmp6], %[offset], 0x08)
"mov.d %[ftmp7], %[ftmp3] \n\t"
"psubush %[ftmp3], %[ftmp3], %[ftmp6] \n\t"
"xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"xor %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psubh %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
"psubh %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
MMI_SDC1(%[ftmp1], %[block], 0x00)
MMI_SDC1(%[ftmp3], %[block], 0x08)
"mov.d %[ftmp1], %[ftmp5] \n\t"
"mov.d %[ftmp3], %[ftmp7] \n\t"
"punpcklhw %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
"punpckhhw %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
"punpcklhw %[ftmp7], %[ftmp7], %[ftmp0] \n\t"
"punpckhhw %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp2], %[sum], 0x00)
"paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[sum], 0x08)
"paddw %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[sum], 0x10)
"paddw %[ftmp7], %[ftmp7], %[ftmp2] \n\t"
MMI_LDC1(%[ftmp2], %[sum], 0x18)
"paddw %[ftmp3], %[ftmp3], %[ftmp2] \n\t"
MMI_SDC1(%[ftmp5], %[sum], 0x00)
MMI_SDC1(%[ftmp1], %[sum], 0x08)
MMI_SDC1(%[ftmp7], %[sum], 0x10)
MMI_SDC1(%[ftmp3], %[sum], 0x18)
PTR_ADDIU "%[block], %[block], 0x10 \n\t"
PTR_ADDIU "%[sum], %[sum], 0x20 \n\t"
PTR_SUBU "%[addr0], %[block1], %[block] \n\t"
PTR_ADDIU "%[offset], %[offset], 0x10 \n\t"
"bgtz %[addr0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]),
RESTRICT_ASM_ALL64
[addr0]"=&r"(addr[0]),
[block]"+&r"(block), [sum]"+&r"(sum),
[offset]"+&r"(offset)
: [block1]"r"(block+64)
: "memory"
);
}

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "h263dsp_mips.h"
static void h263_dct_unquantize_msa(int16_t *block, int16_t qmul,
int16_t qadd, int8_t n_coeffs,
uint8_t loop_start)
{
int16_t *block_dup = block;
int32_t level, cnt;
v8i16 block_vec, qmul_vec, qadd_vec, sub;
v8i16 add, mask, mul, zero_mask;
qmul_vec = __msa_fill_h(qmul);
qadd_vec = __msa_fill_h(qadd);
for (cnt = 0; cnt < (n_coeffs >> 3); cnt++) {
block_vec = LD_SH(block_dup + loop_start);
mask = __msa_clti_s_h(block_vec, 0);
zero_mask = __msa_ceqi_h(block_vec, 0);
mul = block_vec * qmul_vec;
sub = mul - qadd_vec;
add = mul + qadd_vec;
add = (v8i16) __msa_bmnz_v((v16u8) add, (v16u8) sub, (v16u8) mask);
block_vec = (v8i16) __msa_bmnz_v((v16u8) add, (v16u8) block_vec,
(v16u8) zero_mask);
ST_SH(block_vec, block_dup + loop_start);
block_dup += 8;
}
cnt = ((n_coeffs >> 3) * 8) + loop_start;
for (; cnt <= n_coeffs; cnt++) {
level = block[cnt];
if (level) {
if (level < 0) {
level = level * qmul - qadd;
} else {
level = level * qmul + qadd;
}
block[cnt] = level;
}
}
}
static int32_t mpeg2_dct_unquantize_inter_msa(int16_t *block,
int32_t qscale,
const int16_t *quant_matrix)
{
int32_t cnt, sum_res = -1;
v8i16 block_vec, block_neg, qscale_vec, mask;
v8i16 block_org0, block_org1, block_org2, block_org3;
v8i16 quant_m0, quant_m1, quant_m2, quant_m3;
v8i16 sum, mul, zero_mask;
v4i32 mul_vec, qscale_l, qscale_r, quant_m_r, quant_m_l;
v4i32 block_l, block_r, sad;
qscale_vec = __msa_fill_h(qscale);
for (cnt = 0; cnt < 2; cnt++) {
LD_SH4(block, 8, block_org0, block_org1, block_org2, block_org3);
LD_SH4(quant_matrix, 8, quant_m0, quant_m1, quant_m2, quant_m3);
mask = __msa_clti_s_h(block_org0, 0);
zero_mask = __msa_ceqi_h(block_org0, 0);
block_neg = -block_org0;
block_vec = (v8i16) __msa_bmnz_v((v16u8) block_org0, (v16u8) block_neg,
(v16u8) mask);
block_vec <<= 1;
block_vec += 1;
UNPCK_SH_SW(block_vec, block_r, block_l);
UNPCK_SH_SW(qscale_vec, qscale_r, qscale_l);
UNPCK_SH_SW(quant_m0, quant_m_r, quant_m_l);
mul_vec = block_l * qscale_l;
mul_vec *= quant_m_l;
block_l = mul_vec >> 4;
mul_vec = block_r * qscale_r;
mul_vec *= quant_m_r;
block_r = mul_vec >> 4;
mul = (v8i16) __msa_pckev_h((v8i16) block_l, (v8i16) block_r);
block_neg = - mul;
sum = (v8i16) __msa_bmnz_v((v16u8) mul, (v16u8) block_neg,
(v16u8) mask);
sum = (v8i16) __msa_bmnz_v((v16u8) sum, (v16u8) block_org0,
(v16u8) zero_mask);
ST_SH(sum, block);
block += 8;
quant_matrix += 8;
sad = __msa_hadd_s_w(sum, sum);
sum_res += HADD_SW_S32(sad);
mask = __msa_clti_s_h(block_org1, 0);
zero_mask = __msa_ceqi_h(block_org1, 0);
block_neg = - block_org1;
block_vec = (v8i16) __msa_bmnz_v((v16u8) block_org1, (v16u8) block_neg,
(v16u8) mask);
block_vec <<= 1;
block_vec += 1;
UNPCK_SH_SW(block_vec, block_r, block_l);
UNPCK_SH_SW(qscale_vec, qscale_r, qscale_l);
UNPCK_SH_SW(quant_m1, quant_m_r, quant_m_l);
mul_vec = block_l * qscale_l;
mul_vec *= quant_m_l;
block_l = mul_vec >> 4;
mul_vec = block_r * qscale_r;
mul_vec *= quant_m_r;
block_r = mul_vec >> 4;
mul = __msa_pckev_h((v8i16) block_l, (v8i16) block_r);
block_neg = - mul;
sum = (v8i16) __msa_bmnz_v((v16u8) mul, (v16u8) block_neg,
(v16u8) mask);
sum = (v8i16) __msa_bmnz_v((v16u8) sum, (v16u8) block_org1,
(v16u8) zero_mask);
ST_SH(sum, block);
block += 8;
quant_matrix += 8;
sad = __msa_hadd_s_w(sum, sum);
sum_res += HADD_SW_S32(sad);
mask = __msa_clti_s_h(block_org2, 0);
zero_mask = __msa_ceqi_h(block_org2, 0);
block_neg = - block_org2;
block_vec = (v8i16) __msa_bmnz_v((v16u8) block_org2, (v16u8) block_neg,
(v16u8) mask);
block_vec <<= 1;
block_vec += 1;
UNPCK_SH_SW(block_vec, block_r, block_l);
UNPCK_SH_SW(qscale_vec, qscale_r, qscale_l);
UNPCK_SH_SW(quant_m2, quant_m_r, quant_m_l);
mul_vec = block_l * qscale_l;
mul_vec *= quant_m_l;
block_l = mul_vec >> 4;
mul_vec = block_r * qscale_r;
mul_vec *= quant_m_r;
block_r = mul_vec >> 4;
mul = __msa_pckev_h((v8i16) block_l, (v8i16) block_r);
block_neg = - mul;
sum = (v8i16) __msa_bmnz_v((v16u8) mul, (v16u8) block_neg,
(v16u8) mask);
sum = (v8i16) __msa_bmnz_v((v16u8) sum, (v16u8) block_org2,
(v16u8) zero_mask);
ST_SH(sum, block);
block += 8;
quant_matrix += 8;
sad = __msa_hadd_s_w(sum, sum);
sum_res += HADD_SW_S32(sad);
mask = __msa_clti_s_h(block_org3, 0);
zero_mask = __msa_ceqi_h(block_org3, 0);
block_neg = - block_org3;
block_vec = (v8i16) __msa_bmnz_v((v16u8) block_org3, (v16u8) block_neg,
(v16u8) mask);
block_vec <<= 1;
block_vec += 1;
UNPCK_SH_SW(block_vec, block_r, block_l);
UNPCK_SH_SW(qscale_vec, qscale_r, qscale_l);
UNPCK_SH_SW(quant_m3, quant_m_r, quant_m_l);
mul_vec = block_l * qscale_l;
mul_vec *= quant_m_l;
block_l = mul_vec >> 4;
mul_vec = block_r * qscale_r;
mul_vec *= quant_m_r;
block_r = mul_vec >> 4;
mul = __msa_pckev_h((v8i16) block_l, (v8i16) block_r);
block_neg = - mul;
sum = (v8i16) __msa_bmnz_v((v16u8) mul, (v16u8) block_neg,
(v16u8) mask);
sum = (v8i16) __msa_bmnz_v((v16u8) sum, (v16u8) block_org3,
(v16u8) zero_mask);
ST_SH(sum, block);
block += 8;
quant_matrix += 8;
sad = __msa_hadd_s_w(sum, sum);
sum_res += HADD_SW_S32(sad);
}
return sum_res;
}
void ff_dct_unquantize_h263_intra_msa(MpegEncContext *s,
int16_t *block, int32_t index,
int32_t qscale)
{
int32_t qmul, qadd;
int32_t nCoeffs;
av_assert2(s->block_last_index[index] >= 0 || s->h263_aic);
qmul = qscale << 1;
if (!s->h263_aic) {
block[0] *= index < 4 ? s->y_dc_scale : s->c_dc_scale;
qadd = (qscale - 1) | 1;
} else {
qadd = 0;
}
if (s->ac_pred)
nCoeffs = 63;
else
nCoeffs = s->inter_scantable.raster_end[s->block_last_index[index]];
h263_dct_unquantize_msa(block, qmul, qadd, nCoeffs, 1);
}
void ff_dct_unquantize_h263_inter_msa(MpegEncContext *s,
int16_t *block, int32_t index,
int32_t qscale)
{
int32_t qmul, qadd;
int32_t nCoeffs;
av_assert2(s->block_last_index[index] >= 0);
qadd = (qscale - 1) | 1;
qmul = qscale << 1;
nCoeffs = s->inter_scantable.raster_end[s->block_last_index[index]];
h263_dct_unquantize_msa(block, qmul, qadd, nCoeffs, 0);
}
void ff_dct_unquantize_mpeg2_inter_msa(MpegEncContext *s,
int16_t *block, int32_t index,
int32_t qscale)
{
const uint16_t *quant_matrix;
int32_t sum = -1;
quant_matrix = s->inter_matrix;
sum = mpeg2_dct_unquantize_inter_msa(block, qscale, quant_matrix);
block[63] ^= sum & 1;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavcodec/bit_depth_template.c"
#include "h263dsp_mips.h"
#if HAVE_MSA
static av_cold void mpegvideoencdsp_init_msa(MpegvideoEncDSPContext *c,
AVCodecContext *avctx)
{
#if BIT_DEPTH == 8
c->pix_sum = ff_pix_sum_msa;
#endif
}
#endif // #if HAVE_MSA
av_cold void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c,
AVCodecContext *avctx)
{
#if HAVE_MSA
mpegvideoencdsp_init_msa(c, avctx);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h263dsp_mips.h"
#include "libavutil/mips/generic_macros_msa.h"
static int32_t sum_u8src_16width_msa(uint8_t *src, int32_t stride)
{
uint32_t sum = 0;
v16u8 in0, in1, in2, in3, in4, in5, in6, in7;
v16u8 in8, in9, in10, in11, in12, in13, in14, in15;
LD_UB8(src, stride, in0, in1, in2, in3, in4, in5, in6, in7);
src += (8 * stride);
LD_UB8(src, stride, in8, in9, in10, in11, in12, in13, in14, in15);
HADD_UB4_UB(in0, in1, in2, in3, in0, in1, in2, in3);
HADD_UB4_UB(in4, in5, in6, in7, in4, in5, in6, in7);
HADD_UB4_UB(in8, in9, in10, in11, in8, in9, in10, in11);
HADD_UB4_UB(in12, in13, in14, in15, in12, in13, in14, in15);
sum = HADD_UH_U32(in0);
sum += HADD_UH_U32(in1);
sum += HADD_UH_U32(in2);
sum += HADD_UH_U32(in3);
sum += HADD_UH_U32(in4);
sum += HADD_UH_U32(in5);
sum += HADD_UH_U32(in6);
sum += HADD_UH_U32(in7);
sum += HADD_UH_U32(in8);
sum += HADD_UH_U32(in9);
sum += HADD_UH_U32(in10);
sum += HADD_UH_U32(in11);
sum += HADD_UH_U32(in12);
sum += HADD_UH_U32(in13);
sum += HADD_UH_U32(in14);
sum += HADD_UH_U32(in15);
return sum;
}
int ff_pix_sum_msa(uint8_t *pix, int line_size)
{
return sum_u8src_16width_msa(pix, line_size);
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pixblockdsp_mips.h"
#if HAVE_MSA
static av_cold void pixblockdsp_init_msa(PixblockDSPContext *c,
AVCodecContext *avctx,
unsigned high_bit_depth)
{
c->diff_pixels = ff_diff_pixels_msa;
switch (avctx->bits_per_raw_sample) {
case 9:
case 10:
case 12:
case 14:
c->get_pixels = ff_get_pixels_16_msa;
break;
default:
if (avctx->bits_per_raw_sample <= 8 || avctx->codec_type !=
AVMEDIA_TYPE_VIDEO) {
c->get_pixels = ff_get_pixels_8_msa;
}
break;
}
}
#endif // #if HAVE_MSA
#if HAVE_MMI
static av_cold void pixblockdsp_init_mmi(PixblockDSPContext *c,
AVCodecContext *avctx, unsigned high_bit_depth)
{
c->diff_pixels = ff_diff_pixels_mmi;
if (!high_bit_depth || avctx->codec_type != AVMEDIA_TYPE_VIDEO) {
c->get_pixels = ff_get_pixels_8_mmi;
}
}
#endif /* HAVE_MMI */
void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
#if HAVE_MMI
pixblockdsp_init_mmi(c, avctx, high_bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
pixblockdsp_init_msa(c, avctx, high_bit_depth);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
* Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_PIXBLOCKDSP_MIPS_H
#define AVCODEC_MIPS_PIXBLOCKDSP_MIPS_H
#include "../mpegvideo.h"
void ff_diff_pixels_msa(int16_t *av_restrict block, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride);
void ff_get_pixels_16_msa(int16_t *restrict dst, const uint8_t *src,
ptrdiff_t stride);
void ff_get_pixels_8_msa(int16_t *restrict dst, const uint8_t *src,
ptrdiff_t stride);
void ff_get_pixels_8_mmi(int16_t *av_restrict block, const uint8_t *pixels,
ptrdiff_t stride);
void ff_diff_pixels_mmi(int16_t *av_restrict block, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride);
#endif // #ifndef AVCODEC_MIPS_PIXBLOCKDSP_MIPS_H

View File

@@ -0,0 +1,135 @@
/*
* Loongson SIMD optimized pixblockdsp
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pixblockdsp_mips.h"
#include "libavutil/mips/asmdefs.h"
#include "libavutil/mips/mmiutils.h"
void ff_get_pixels_8_mmi(int16_t *av_restrict block, const uint8_t *pixels,
ptrdiff_t stride)
{
double ftmp[7];
DECLARE_VAR_ALL64;
DECLARE_VAR_ADDRT;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp1], %[pixels], 0x00)
MMI_LDXC1(%[ftmp2], %[pixels], %[stride], 0x00)
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
MMI_SDC1(%[ftmp3], %[block], 0x00)
MMI_SDC1(%[ftmp4], %[block], 0x08)
MMI_SDC1(%[ftmp5], %[block], 0x10)
MMI_SDC1(%[ftmp6], %[block], 0x18)
PTR_ADDU "%[pixels], %[pixels], %[stride_x2] \n\t"
MMI_LDC1(%[ftmp1], %[pixels], 0x00)
MMI_LDXC1(%[ftmp2], %[pixels], %[stride], 0x00)
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
MMI_SDC1(%[ftmp3], %[block], 0x20)
MMI_SDC1(%[ftmp4], %[block], 0x28)
MMI_SDC1(%[ftmp5], %[block], 0x30)
MMI_SDC1(%[ftmp6], %[block], 0x38)
PTR_ADDU "%[pixels], %[pixels], %[stride_x2] \n\t"
MMI_LDC1(%[ftmp1], %[pixels], 0x00)
MMI_LDXC1(%[ftmp2], %[pixels], %[stride], 0x00)
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
MMI_SDC1(%[ftmp3], %[block], 0x40)
MMI_SDC1(%[ftmp4], %[block], 0x48)
MMI_SDC1(%[ftmp5], %[block], 0x50)
MMI_SDC1(%[ftmp6], %[block], 0x58)
PTR_ADDU "%[pixels], %[pixels], %[stride_x2] \n\t"
MMI_LDC1(%[ftmp1], %[pixels], 0x00)
MMI_LDXC1(%[ftmp2], %[pixels], %[stride], 0x00)
"punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t"
"punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t"
"punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
MMI_SDC1(%[ftmp3], %[block], 0x60)
MMI_SDC1(%[ftmp4], %[block], 0x68)
MMI_SDC1(%[ftmp5], %[block], 0x70)
MMI_SDC1(%[ftmp6], %[block], 0x78)
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]),
RESTRICT_ASM_ALL64
RESTRICT_ASM_ADDRT
[pixels]"+&r"(pixels)
: [block]"r"((mips_reg)block), [stride]"r"((mips_reg)stride),
[stride_x2]"r"((mips_reg)(stride<<1))
: "memory"
);
}
void ff_diff_pixels_mmi(int16_t *av_restrict block, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride)
{
double ftmp[5];
mips_reg tmp[1];
DECLARE_VAR_ALL64;
__asm__ volatile (
"li %[tmp0], 0x08 \n\t"
"xor %[ftmp4], %[ftmp4], %[ftmp4] \n\t"
"1: \n\t"
MMI_LDC1(%[ftmp0], %[src1], 0x00)
"or %[ftmp1], %[ftmp0], %[ftmp0] \n\t"
MMI_LDC1(%[ftmp2], %[src2], 0x00)
"or %[ftmp3], %[ftmp2], %[ftmp2] \n\t"
"punpcklbh %[ftmp0], %[ftmp0], %[ftmp4] \n\t"
"punpckhbh %[ftmp1], %[ftmp1], %[ftmp4] \n\t"
"punpcklbh %[ftmp2], %[ftmp2], %[ftmp4] \n\t"
"punpckhbh %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psubh %[ftmp0], %[ftmp0], %[ftmp2] \n\t"
"psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t"
MMI_SDC1(%[ftmp0], %[block], 0x00)
MMI_SDC1(%[ftmp1], %[block], 0x08)
PTR_ADDI "%[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDIU "%[block], %[block], 0x10 \n\t"
PTR_ADDU "%[src1], %[src1], %[stride] \n\t"
PTR_ADDU "%[src2], %[src2], %[stride] \n\t"
"bgtz %[tmp0], 1b \n\t"
: [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
[ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
[ftmp4]"=&f"(ftmp[4]),
[tmp0]"=&r"(tmp[0]),
RESTRICT_ASM_ALL64
[block]"+&r"(block), [src1]"+&r"(src1),
[src2]"+&r"(src2)
: [stride]"r"((mips_reg)stride)
: "memory"
);
}

View File

@@ -0,0 +1,143 @@
/*
* Copyright (c) 2015 Shivraj Patil (Shivraj.Patil@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "pixblockdsp_mips.h"
static void diff_pixels_msa(int16_t *block, const uint8_t *src1,
const uint8_t *src2, int32_t stride)
{
v16u8 in10, in11, in12, in13, in14, in15, in16, in17;
v16u8 in20, in21, in22, in23, in24, in25, in26, in27;
v8i16 out0, out1, out2, out3, out4, out5, out6, out7;
LD_UB8(src1, stride, in10, in11, in12, in13, in14, in15, in16, in17);
LD_UB8(src2, stride, in20, in21, in22, in23, in24, in25, in26, in27);
ILVR_B4_SH(in10, in20, in11, in21, in12, in22, in13, in23,
out0, out1, out2, out3);
ILVR_B4_SH(in14, in24, in15, in25, in16, in26, in17, in27,
out4, out5, out6, out7);
HSUB_UB4_SH(out0, out1, out2, out3, out0, out1, out2, out3);
HSUB_UB4_SH(out4, out5, out6, out7, out4, out5, out6, out7);
ST_SH8(out0, out1, out2, out3, out4, out5, out6, out7, block, 8);
}
static void copy_8bit_to_16bit_width8_msa(const uint8_t *src, int32_t src_stride,
int16_t *dst, int32_t dst_stride,
int32_t height)
{
uint8_t *dst_ptr;
int32_t cnt;
v16u8 src0, src1, src2, src3;
v16i8 zero = { 0 };
dst_ptr = (uint8_t *) dst;
for (cnt = (height >> 2); cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
ILVR_B4_UB(zero, src0, zero, src1, zero, src2, zero, src3,
src0, src1, src2, src3);
ST_UB4(src0, src1, src2, src3, dst_ptr, (dst_stride * 2));
dst_ptr += (4 * 2 * dst_stride);
}
}
static void copy_16multx8mult_msa(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
int32_t height, int32_t width)
{
int32_t cnt, loop_cnt;
const uint8_t *src_tmp;
uint8_t *dst_tmp;
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
for (cnt = (width >> 4); cnt--;) {
src_tmp = src;
dst_tmp = dst;
for (loop_cnt = (height >> 3); loop_cnt--;) {
LD_UB8(src_tmp, src_stride,
src0, src1, src2, src3, src4, src5, src6, src7);
src_tmp += (8 * src_stride);
ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7,
dst_tmp, dst_stride);
dst_tmp += (8 * dst_stride);
}
src += 16;
dst += 16;
}
}
static void copy_width16_msa(const uint8_t *src, int32_t src_stride,
uint8_t *dst, int32_t dst_stride,
int32_t height)
{
int32_t cnt;
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
if (0 == height % 12) {
for (cnt = (height / 12); cnt--;) {
LD_UB8(src, src_stride,
src0, src1, src2, src3, src4, src5, src6, src7);
src += (8 * src_stride);
ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7,
dst, dst_stride);
dst += (8 * dst_stride);
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
ST_UB4(src0, src1, src2, src3, dst, dst_stride);
dst += (4 * dst_stride);
}
} else if (0 == height % 8) {
copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16);
} else if (0 == height % 4) {
for (cnt = (height >> 2); cnt--;) {
LD_UB4(src, src_stride, src0, src1, src2, src3);
src += (4 * src_stride);
ST_UB4(src0, src1, src2, src3, dst, dst_stride);
dst += (4 * dst_stride);
}
}
}
void ff_get_pixels_16_msa(int16_t *av_restrict dest, const uint8_t *src,
ptrdiff_t stride)
{
copy_width16_msa(src, stride, (uint8_t *) dest, 16, 8);
}
void ff_get_pixels_8_msa(int16_t *av_restrict dest, const uint8_t *src,
ptrdiff_t stride)
{
copy_8bit_to_16bit_width8_msa(src, stride, dest, 8, 8);
}
void ff_diff_pixels_msa(int16_t *av_restrict block, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride)
{
diff_pixels_msa(block, src1, src2, stride);
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "qpeldsp_mips.h"
#if HAVE_MSA
static av_cold void qpeldsp_init_msa(QpelDSPContext *c)
{
c->put_qpel_pixels_tab[0][0] = ff_copy_16x16_msa;
c->put_qpel_pixels_tab[0][1] = ff_horiz_mc_qpel_aver_src0_16width_msa;
c->put_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_16width_msa;
c->put_qpel_pixels_tab[0][3] = ff_horiz_mc_qpel_aver_src1_16width_msa;
c->put_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_aver_src0_16x16_msa;
c->put_qpel_pixels_tab[0][5] = ff_hv_mc_qpel_aver_hv_src00_16x16_msa;
c->put_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_aver_v_src0_16x16_msa;
c->put_qpel_pixels_tab[0][7] = ff_hv_mc_qpel_aver_hv_src10_16x16_msa;
c->put_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_16x16_msa;
c->put_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_aver_h_src0_16x16_msa;
c->put_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_16x16_msa;
c->put_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_aver_h_src1_16x16_msa;
c->put_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_aver_src1_16x16_msa;
c->put_qpel_pixels_tab[0][13] = ff_hv_mc_qpel_aver_hv_src01_16x16_msa;
c->put_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_aver_v_src1_16x16_msa;
c->put_qpel_pixels_tab[0][15] = ff_hv_mc_qpel_aver_hv_src11_16x16_msa;
c->put_qpel_pixels_tab[1][0] = ff_copy_8x8_msa;
c->put_qpel_pixels_tab[1][1] = ff_horiz_mc_qpel_aver_src0_8width_msa;
c->put_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_8width_msa;
c->put_qpel_pixels_tab[1][3] = ff_horiz_mc_qpel_aver_src1_8width_msa;
c->put_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_aver_src0_8x8_msa;
c->put_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_aver_hv_src00_8x8_msa;
c->put_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_aver_v_src0_8x8_msa;
c->put_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_aver_hv_src10_8x8_msa;
c->put_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_8x8_msa;
c->put_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_aver_h_src0_8x8_msa;
c->put_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_8x8_msa;
c->put_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_aver_h_src1_8x8_msa;
c->put_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_aver_src1_8x8_msa;
c->put_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_aver_hv_src01_8x8_msa;
c->put_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_aver_v_src1_8x8_msa;
c->put_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_aver_hv_src11_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[0][0] = ff_copy_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][1] =
ff_horiz_mc_qpel_no_rnd_aver_src0_16width_msa;
c->put_no_rnd_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_no_rnd_16width_msa;
c->put_no_rnd_qpel_pixels_tab[0][3] =
ff_horiz_mc_qpel_no_rnd_aver_src1_16width_msa;
c->put_no_rnd_qpel_pixels_tab[0][4] =
ff_vert_mc_qpel_no_rnd_aver_src0_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][5] =
ff_hv_mc_qpel_no_rnd_aver_hv_src00_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][6] =
ff_hv_mc_qpel_no_rnd_aver_v_src0_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][7] =
ff_hv_mc_qpel_no_rnd_aver_hv_src10_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_no_rnd_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][9] =
ff_hv_mc_qpel_no_rnd_aver_h_src0_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_no_rnd_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][11] =
ff_hv_mc_qpel_no_rnd_aver_h_src1_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][12] =
ff_vert_mc_qpel_no_rnd_aver_src1_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][13] =
ff_hv_mc_qpel_no_rnd_aver_hv_src01_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][14] =
ff_hv_mc_qpel_no_rnd_aver_v_src1_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[0][15] =
ff_hv_mc_qpel_no_rnd_aver_hv_src11_16x16_msa;
c->put_no_rnd_qpel_pixels_tab[1][0] = ff_copy_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][1] =
ff_horiz_mc_qpel_no_rnd_aver_src0_8width_msa;
c->put_no_rnd_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_no_rnd_8width_msa;
c->put_no_rnd_qpel_pixels_tab[1][3] =
ff_horiz_mc_qpel_no_rnd_aver_src1_8width_msa;
c->put_no_rnd_qpel_pixels_tab[1][4] =
ff_vert_mc_qpel_no_rnd_aver_src0_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][5] =
ff_hv_mc_qpel_no_rnd_aver_hv_src00_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][6] =
ff_hv_mc_qpel_no_rnd_aver_v_src0_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][7] =
ff_hv_mc_qpel_no_rnd_aver_hv_src10_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_no_rnd_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][9] =
ff_hv_mc_qpel_no_rnd_aver_h_src0_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_no_rnd_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][11] =
ff_hv_mc_qpel_no_rnd_aver_h_src1_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][12] =
ff_vert_mc_qpel_no_rnd_aver_src1_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][13] =
ff_hv_mc_qpel_no_rnd_aver_hv_src01_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][14] =
ff_hv_mc_qpel_no_rnd_aver_v_src1_8x8_msa;
c->put_no_rnd_qpel_pixels_tab[1][15] =
ff_hv_mc_qpel_no_rnd_aver_hv_src11_8x8_msa;
c->avg_qpel_pixels_tab[0][0] = ff_avg_width16_msa;
c->avg_qpel_pixels_tab[0][1] =
ff_horiz_mc_qpel_avg_dst_aver_src0_16width_msa;
c->avg_qpel_pixels_tab[0][2] = ff_horiz_mc_qpel_avg_dst_16width_msa;
c->avg_qpel_pixels_tab[0][3] =
ff_horiz_mc_qpel_avg_dst_aver_src1_16width_msa;
c->avg_qpel_pixels_tab[0][4] = ff_vert_mc_qpel_avg_dst_aver_src0_16x16_msa;
c->avg_qpel_pixels_tab[0][5] =
ff_hv_mc_qpel_avg_dst_aver_hv_src00_16x16_msa;
c->avg_qpel_pixels_tab[0][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_16x16_msa;
c->avg_qpel_pixels_tab[0][7] =
ff_hv_mc_qpel_avg_dst_aver_hv_src10_16x16_msa;
c->avg_qpel_pixels_tab[0][8] = ff_vert_mc_qpel_avg_dst_16x16_msa;
c->avg_qpel_pixels_tab[0][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_16x16_msa;
c->avg_qpel_pixels_tab[0][10] = ff_hv_mc_qpel_avg_dst_16x16_msa;
c->avg_qpel_pixels_tab[0][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_16x16_msa;
c->avg_qpel_pixels_tab[0][12] = ff_vert_mc_qpel_avg_dst_aver_src1_16x16_msa;
c->avg_qpel_pixels_tab[0][13] =
ff_hv_mc_qpel_avg_dst_aver_hv_src01_16x16_msa;
c->avg_qpel_pixels_tab[0][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_16x16_msa;
c->avg_qpel_pixels_tab[0][15] =
ff_hv_mc_qpel_avg_dst_aver_hv_src11_16x16_msa;
c->avg_qpel_pixels_tab[1][0] = ff_avg_width8_msa;
c->avg_qpel_pixels_tab[1][1] =
ff_horiz_mc_qpel_avg_dst_aver_src0_8width_msa;
c->avg_qpel_pixels_tab[1][2] = ff_horiz_mc_qpel_avg_dst_8width_msa;
c->avg_qpel_pixels_tab[1][3] =
ff_horiz_mc_qpel_avg_dst_aver_src1_8width_msa;
c->avg_qpel_pixels_tab[1][4] = ff_vert_mc_qpel_avg_dst_aver_src0_8x8_msa;
c->avg_qpel_pixels_tab[1][5] = ff_hv_mc_qpel_avg_dst_aver_hv_src00_8x8_msa;
c->avg_qpel_pixels_tab[1][6] = ff_hv_mc_qpel_avg_dst_aver_v_src0_8x8_msa;
c->avg_qpel_pixels_tab[1][7] = ff_hv_mc_qpel_avg_dst_aver_hv_src10_8x8_msa;
c->avg_qpel_pixels_tab[1][8] = ff_vert_mc_qpel_avg_dst_8x8_msa;
c->avg_qpel_pixels_tab[1][9] = ff_hv_mc_qpel_avg_dst_aver_h_src0_8x8_msa;
c->avg_qpel_pixels_tab[1][10] = ff_hv_mc_qpel_avg_dst_8x8_msa;
c->avg_qpel_pixels_tab[1][11] = ff_hv_mc_qpel_avg_dst_aver_h_src1_8x8_msa;
c->avg_qpel_pixels_tab[1][12] = ff_vert_mc_qpel_avg_dst_aver_src1_8x8_msa;
c->avg_qpel_pixels_tab[1][13] = ff_hv_mc_qpel_avg_dst_aver_hv_src01_8x8_msa;
c->avg_qpel_pixels_tab[1][14] = ff_hv_mc_qpel_avg_dst_aver_v_src1_8x8_msa;
c->avg_qpel_pixels_tab[1][15] = ff_hv_mc_qpel_avg_dst_aver_hv_src11_8x8_msa;
}
#endif // #if HAVE_MSA
void ff_qpeldsp_init_mips(QpelDSPContext *c)
{
#if HAVE_MSA
qpeldsp_init_msa(c);
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,261 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_QPELDSP_MIPS_H
#define AVCODEC_MIPS_QPELDSP_MIPS_H
#include "../mpegvideo.h"
void ff_copy_8x8_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_copy_16x16_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_avg_width8_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_avg_width16_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_horiz_mc_qpel_aver_src0_8width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_aver_src0_16width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_8width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_16width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_aver_src1_8width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_aver_src1_16width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_aver_src0_8width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_aver_src0_16width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_8width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_16width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_aver_src1_8width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_no_rnd_aver_src1_16width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_aver_src0_8width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_aver_src0_16width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_8width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_16width_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_aver_src1_8width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_horiz_mc_qpel_avg_dst_aver_src1_16width_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_aver_src0_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_aver_src0_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_aver_src1_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_aver_src1_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_aver_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_aver_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_aver_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_no_rnd_aver_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_aver_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_aver_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_aver_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_vert_mc_qpel_avg_dst_aver_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src00_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src00_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_v_src0_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_v_src0_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src10_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src10_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_h_src0_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_h_src0_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_8x8_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride);
void ff_hv_mc_qpel_aver_h_src1_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_h_src1_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src01_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src01_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_v_src1_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_v_src1_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src11_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_aver_hv_src11_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src00_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src00_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_v_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_v_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src10_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src10_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_h_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_h_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_h_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_h_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src01_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src01_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_v_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_v_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src11_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_avg_dst_aver_hv_src11_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src00_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src00_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_v_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_v_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src10_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src10_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_h_src0_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_h_src0_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_16x16_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_8x8_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_h_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_h_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src01_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src01_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_v_src1_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_v_src1_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src11_16x16_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
void ff_hv_mc_qpel_no_rnd_aver_hv_src11_8x8_msa(uint8_t *dst,
const uint8_t *src,
ptrdiff_t stride);
#endif // #ifndef AVCODEC_MIPS_QPELDSP_MIPS_H

6470
externals/ffmpeg/libavcodec/mips/qpeldsp_msa.c vendored Executable file

File diff suppressed because it is too large Load Diff

911
externals/ffmpeg/libavcodec/mips/sbrdsp_mips.c vendored Executable file
View File

@@ -0,0 +1,911 @@
/*
* Copyright (c) 2012
* MIPS Technologies, Inc., California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Authors: Darko Laus (darko@mips.com)
* Djordje Pesut (djordje@mips.com)
* Mirjana Vulin (mvulin@mips.com)
*
* AAC Spectral Band Replication decoding functions optimized for MIPS
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Reference: libavcodec/sbrdsp.c
*/
#include "config.h"
#include "libavcodec/sbrdsp.h"
#include "libavutil/mips/asmdefs.h"
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
static void sbr_qmf_pre_shuffle_mips(float *z)
{
int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6;
float *z1 = &z[66];
float *z2 = &z[59];
float *z3 = &z[2];
float *z4 = z1 + 60;
/* loop unrolled 5 times */
__asm__ volatile (
"lui %[Temp6], 0x8000 \n\t"
"1: \n\t"
"lw %[Temp1], 0(%[z2]) \n\t"
"lw %[Temp2], 4(%[z2]) \n\t"
"lw %[Temp3], 8(%[z2]) \n\t"
"lw %[Temp4], 12(%[z2]) \n\t"
"lw %[Temp5], 16(%[z2]) \n\t"
"xor %[Temp1], %[Temp1], %[Temp6] \n\t"
"xor %[Temp2], %[Temp2], %[Temp6] \n\t"
"xor %[Temp3], %[Temp3], %[Temp6] \n\t"
"xor %[Temp4], %[Temp4], %[Temp6] \n\t"
"xor %[Temp5], %[Temp5], %[Temp6] \n\t"
PTR_ADDIU "%[z2], %[z2], -20 \n\t"
"sw %[Temp1], 32(%[z1]) \n\t"
"sw %[Temp2], 24(%[z1]) \n\t"
"sw %[Temp3], 16(%[z1]) \n\t"
"sw %[Temp4], 8(%[z1]) \n\t"
"sw %[Temp5], 0(%[z1]) \n\t"
"lw %[Temp1], 0(%[z3]) \n\t"
"lw %[Temp2], 4(%[z3]) \n\t"
"lw %[Temp3], 8(%[z3]) \n\t"
"lw %[Temp4], 12(%[z3]) \n\t"
"lw %[Temp5], 16(%[z3]) \n\t"
"sw %[Temp1], 4(%[z1]) \n\t"
"sw %[Temp2], 12(%[z1]) \n\t"
"sw %[Temp3], 20(%[z1]) \n\t"
"sw %[Temp4], 28(%[z1]) \n\t"
"sw %[Temp5], 36(%[z1]) \n\t"
PTR_ADDIU "%[z3], %[z3], 20 \n\t"
PTR_ADDIU "%[z1], %[z1], 40 \n\t"
"bne %[z1], %[z4], 1b \n\t"
"lw %[Temp1], 132(%[z]) \n\t"
"lw %[Temp2], 128(%[z]) \n\t"
"lw %[Temp3], 0(%[z]) \n\t"
"lw %[Temp4], 4(%[z]) \n\t"
"xor %[Temp1], %[Temp1], %[Temp6] \n\t"
"sw %[Temp1], 504(%[z]) \n\t"
"sw %[Temp2], 508(%[z]) \n\t"
"sw %[Temp3], 256(%[z]) \n\t"
"sw %[Temp4], 260(%[z]) \n\t"
: [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
[Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
[Temp5]"=&r"(Temp5), [Temp6]"=&r"(Temp6),
[z1]"+r"(z1), [z2]"+r"(z2), [z3]"+r"(z3)
: [z4]"r"(z4), [z]"r"(z)
: "memory"
);
}
static void sbr_qmf_post_shuffle_mips(float W[32][2], const float *z)
{
int Temp1, Temp2, Temp3, Temp4, Temp5;
float *W_ptr = (float *)W;
float *z1 = (float *)z;
float *z2 = (float *)&z[60];
float *z_end = z1 + 32;
/* loop unrolled 4 times */
__asm__ volatile (
"lui %[Temp5], 0x8000 \n\t"
"1: \n\t"
"lw %[Temp1], 0(%[z2]) \n\t"
"lw %[Temp2], 4(%[z2]) \n\t"
"lw %[Temp3], 8(%[z2]) \n\t"
"lw %[Temp4], 12(%[z2]) \n\t"
"xor %[Temp1], %[Temp1], %[Temp5] \n\t"
"xor %[Temp2], %[Temp2], %[Temp5] \n\t"
"xor %[Temp3], %[Temp3], %[Temp5] \n\t"
"xor %[Temp4], %[Temp4], %[Temp5] \n\t"
PTR_ADDIU "%[z2], %[z2], -16 \n\t"
"sw %[Temp1], 24(%[W_ptr]) \n\t"
"sw %[Temp2], 16(%[W_ptr]) \n\t"
"sw %[Temp3], 8(%[W_ptr]) \n\t"
"sw %[Temp4], 0(%[W_ptr]) \n\t"
"lw %[Temp1], 0(%[z1]) \n\t"
"lw %[Temp2], 4(%[z1]) \n\t"
"lw %[Temp3], 8(%[z1]) \n\t"
"lw %[Temp4], 12(%[z1]) \n\t"
"sw %[Temp1], 4(%[W_ptr]) \n\t"
"sw %[Temp2], 12(%[W_ptr]) \n\t"
"sw %[Temp3], 20(%[W_ptr]) \n\t"
"sw %[Temp4], 28(%[W_ptr]) \n\t"
PTR_ADDIU "%[z1], %[z1], 16 \n\t"
PTR_ADDIU "%[W_ptr],%[W_ptr], 32 \n\t"
"bne %[z1], %[z_end], 1b \n\t"
: [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
[Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
[Temp5]"=&r"(Temp5), [z1]"+r"(z1),
[z2]"+r"(z2), [W_ptr]"+r"(W_ptr)
: [z_end]"r"(z_end)
: "memory"
);
}
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
static void sbr_sum64x5_mips(float *z)
{
int k;
float *z1;
float f1, f2, f3, f4, f5, f6, f7, f8;
for (k = 0; k < 64; k += 8) {
z1 = &z[k];
/* loop unrolled 8 times */
__asm__ volatile (
"lwc1 $f0, 0(%[z1]) \n\t"
"lwc1 $f1, 256(%[z1]) \n\t"
"lwc1 $f2, 4(%[z1]) \n\t"
"lwc1 $f3, 260(%[z1]) \n\t"
"lwc1 $f4, 8(%[z1]) \n\t"
"add.s %[f1], $f0, $f1 \n\t"
"lwc1 $f5, 264(%[z1]) \n\t"
"add.s %[f2], $f2, $f3 \n\t"
"lwc1 $f6, 12(%[z1]) \n\t"
"lwc1 $f7, 268(%[z1]) \n\t"
"add.s %[f3], $f4, $f5 \n\t"
"lwc1 $f8, 16(%[z1]) \n\t"
"lwc1 $f9, 272(%[z1]) \n\t"
"add.s %[f4], $f6, $f7 \n\t"
"lwc1 $f10, 20(%[z1]) \n\t"
"lwc1 $f11, 276(%[z1]) \n\t"
"add.s %[f5], $f8, $f9 \n\t"
"lwc1 $f12, 24(%[z1]) \n\t"
"lwc1 $f13, 280(%[z1]) \n\t"
"add.s %[f6], $f10, $f11 \n\t"
"lwc1 $f14, 28(%[z1]) \n\t"
"lwc1 $f15, 284(%[z1]) \n\t"
"add.s %[f7], $f12, $f13 \n\t"
"lwc1 $f0, 512(%[z1]) \n\t"
"lwc1 $f1, 516(%[z1]) \n\t"
"add.s %[f8], $f14, $f15 \n\t"
"lwc1 $f2, 520(%[z1]) \n\t"
"add.s %[f1], %[f1], $f0 \n\t"
"add.s %[f2], %[f2], $f1 \n\t"
"lwc1 $f3, 524(%[z1]) \n\t"
"add.s %[f3], %[f3], $f2 \n\t"
"lwc1 $f4, 528(%[z1]) \n\t"
"lwc1 $f5, 532(%[z1]) \n\t"
"add.s %[f4], %[f4], $f3 \n\t"
"lwc1 $f6, 536(%[z1]) \n\t"
"add.s %[f5], %[f5], $f4 \n\t"
"add.s %[f6], %[f6], $f5 \n\t"
"lwc1 $f7, 540(%[z1]) \n\t"
"add.s %[f7], %[f7], $f6 \n\t"
"lwc1 $f0, 768(%[z1]) \n\t"
"lwc1 $f1, 772(%[z1]) \n\t"
"add.s %[f8], %[f8], $f7 \n\t"
"lwc1 $f2, 776(%[z1]) \n\t"
"add.s %[f1], %[f1], $f0 \n\t"
"add.s %[f2], %[f2], $f1 \n\t"
"lwc1 $f3, 780(%[z1]) \n\t"
"add.s %[f3], %[f3], $f2 \n\t"
"lwc1 $f4, 784(%[z1]) \n\t"
"lwc1 $f5, 788(%[z1]) \n\t"
"add.s %[f4], %[f4], $f3 \n\t"
"lwc1 $f6, 792(%[z1]) \n\t"
"add.s %[f5], %[f5], $f4 \n\t"
"add.s %[f6], %[f6], $f5 \n\t"
"lwc1 $f7, 796(%[z1]) \n\t"
"add.s %[f7], %[f7], $f6 \n\t"
"lwc1 $f0, 1024(%[z1]) \n\t"
"lwc1 $f1, 1028(%[z1]) \n\t"
"add.s %[f8], %[f8], $f7 \n\t"
"lwc1 $f2, 1032(%[z1]) \n\t"
"add.s %[f1], %[f1], $f0 \n\t"
"add.s %[f2], %[f2], $f1 \n\t"
"lwc1 $f3, 1036(%[z1]) \n\t"
"add.s %[f3], %[f3], $f2 \n\t"
"lwc1 $f4, 1040(%[z1]) \n\t"
"lwc1 $f5, 1044(%[z1]) \n\t"
"add.s %[f4], %[f4], $f3 \n\t"
"lwc1 $f6, 1048(%[z1]) \n\t"
"add.s %[f5], %[f5], $f4 \n\t"
"add.s %[f6], %[f6], $f5 \n\t"
"lwc1 $f7, 1052(%[z1]) \n\t"
"add.s %[f7], %[f7], $f6 \n\t"
"swc1 %[f1], 0(%[z1]) \n\t"
"swc1 %[f2], 4(%[z1]) \n\t"
"add.s %[f8], %[f8], $f7 \n\t"
"swc1 %[f3], 8(%[z1]) \n\t"
"swc1 %[f4], 12(%[z1]) \n\t"
"swc1 %[f5], 16(%[z1]) \n\t"
"swc1 %[f6], 20(%[z1]) \n\t"
"swc1 %[f7], 24(%[z1]) \n\t"
"swc1 %[f8], 28(%[z1]) \n\t"
: [f1]"=&f"(f1), [f2]"=&f"(f2), [f3]"=&f"(f3),
[f4]"=&f"(f4), [f5]"=&f"(f5), [f6]"=&f"(f6),
[f7]"=&f"(f7), [f8]"=&f"(f8)
: [z1]"r"(z1)
: "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
"$f6", "$f7", "$f8", "$f9", "$f10", "$f11",
"$f12", "$f13", "$f14", "$f15",
"memory"
);
}
}
static float sbr_sum_square_mips(float (*x)[2], int n)
{
float sum0 = 0.0f, sum1 = 0.0f;
float *p_x;
float temp0, temp1, temp2, temp3;
float *loop_end;
p_x = &x[0][0];
loop_end = p_x + (n >> 1)*4 - 4;
__asm__ volatile (
".set push \n\t"
".set noreorder \n\t"
"lwc1 %[temp0], 0(%[p_x]) \n\t"
"lwc1 %[temp1], 4(%[p_x]) \n\t"
"lwc1 %[temp2], 8(%[p_x]) \n\t"
"lwc1 %[temp3], 12(%[p_x]) \n\t"
"1: \n\t"
PTR_ADDIU "%[p_x], %[p_x], 16 \n\t"
"madd.s %[sum0], %[sum0], %[temp0], %[temp0] \n\t"
"lwc1 %[temp0], 0(%[p_x]) \n\t"
"madd.s %[sum1], %[sum1], %[temp1], %[temp1] \n\t"
"lwc1 %[temp1], 4(%[p_x]) \n\t"
"madd.s %[sum0], %[sum0], %[temp2], %[temp2] \n\t"
"lwc1 %[temp2], 8(%[p_x]) \n\t"
"madd.s %[sum1], %[sum1], %[temp3], %[temp3] \n\t"
"bne %[p_x], %[loop_end], 1b \n\t"
" lwc1 %[temp3], 12(%[p_x]) \n\t"
"madd.s %[sum0], %[sum0], %[temp0], %[temp0] \n\t"
"madd.s %[sum1], %[sum1], %[temp1], %[temp1] \n\t"
"madd.s %[sum0], %[sum0], %[temp2], %[temp2] \n\t"
"madd.s %[sum1], %[sum1], %[temp3], %[temp3] \n\t"
".set pop \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [sum0]"+f"(sum0), [sum1]"+f"(sum1),
[p_x]"+r"(p_x)
: [loop_end]"r"(loop_end)
: "memory"
);
return sum0 + sum1;
}
static void sbr_qmf_deint_bfly_mips(float *v, const float *src0, const float *src1)
{
int i;
float temp0, temp1, temp2, temp3, temp4, temp5;
float temp6, temp7, temp8, temp9, temp10, temp11;
float *v0 = v;
float *v1 = &v[127];
float *psrc0 = (float*)src0;
float *psrc1 = (float*)&src1[63];
for (i = 0; i < 4; i++) {
/* loop unrolled 16 times */
__asm__ volatile(
"lwc1 %[temp0], 0(%[src0]) \n\t"
"lwc1 %[temp1], 0(%[src1]) \n\t"
"lwc1 %[temp3], 4(%[src0]) \n\t"
"lwc1 %[temp4], -4(%[src1]) \n\t"
"lwc1 %[temp6], 8(%[src0]) \n\t"
"lwc1 %[temp7], -8(%[src1]) \n\t"
"lwc1 %[temp9], 12(%[src0]) \n\t"
"lwc1 %[temp10], -12(%[src1]) \n\t"
"add.s %[temp2], %[temp0], %[temp1] \n\t"
"add.s %[temp5], %[temp3], %[temp4] \n\t"
"add.s %[temp8], %[temp6], %[temp7] \n\t"
"add.s %[temp11], %[temp9], %[temp10] \n\t"
"sub.s %[temp0], %[temp0], %[temp1] \n\t"
"sub.s %[temp3], %[temp3], %[temp4] \n\t"
"sub.s %[temp6], %[temp6], %[temp7] \n\t"
"sub.s %[temp9], %[temp9], %[temp10] \n\t"
"swc1 %[temp2], 0(%[v1]) \n\t"
"swc1 %[temp0], 0(%[v0]) \n\t"
"swc1 %[temp5], -4(%[v1]) \n\t"
"swc1 %[temp3], 4(%[v0]) \n\t"
"swc1 %[temp8], -8(%[v1]) \n\t"
"swc1 %[temp6], 8(%[v0]) \n\t"
"swc1 %[temp11], -12(%[v1]) \n\t"
"swc1 %[temp9], 12(%[v0]) \n\t"
"lwc1 %[temp0], 16(%[src0]) \n\t"
"lwc1 %[temp1], -16(%[src1]) \n\t"
"lwc1 %[temp3], 20(%[src0]) \n\t"
"lwc1 %[temp4], -20(%[src1]) \n\t"
"lwc1 %[temp6], 24(%[src0]) \n\t"
"lwc1 %[temp7], -24(%[src1]) \n\t"
"lwc1 %[temp9], 28(%[src0]) \n\t"
"lwc1 %[temp10], -28(%[src1]) \n\t"
"add.s %[temp2], %[temp0], %[temp1] \n\t"
"add.s %[temp5], %[temp3], %[temp4] \n\t"
"add.s %[temp8], %[temp6], %[temp7] \n\t"
"add.s %[temp11], %[temp9], %[temp10] \n\t"
"sub.s %[temp0], %[temp0], %[temp1] \n\t"
"sub.s %[temp3], %[temp3], %[temp4] \n\t"
"sub.s %[temp6], %[temp6], %[temp7] \n\t"
"sub.s %[temp9], %[temp9], %[temp10] \n\t"
"swc1 %[temp2], -16(%[v1]) \n\t"
"swc1 %[temp0], 16(%[v0]) \n\t"
"swc1 %[temp5], -20(%[v1]) \n\t"
"swc1 %[temp3], 20(%[v0]) \n\t"
"swc1 %[temp8], -24(%[v1]) \n\t"
"swc1 %[temp6], 24(%[v0]) \n\t"
"swc1 %[temp11], -28(%[v1]) \n\t"
"swc1 %[temp9], 28(%[v0]) \n\t"
"lwc1 %[temp0], 32(%[src0]) \n\t"
"lwc1 %[temp1], -32(%[src1]) \n\t"
"lwc1 %[temp3], 36(%[src0]) \n\t"
"lwc1 %[temp4], -36(%[src1]) \n\t"
"lwc1 %[temp6], 40(%[src0]) \n\t"
"lwc1 %[temp7], -40(%[src1]) \n\t"
"lwc1 %[temp9], 44(%[src0]) \n\t"
"lwc1 %[temp10], -44(%[src1]) \n\t"
"add.s %[temp2], %[temp0], %[temp1] \n\t"
"add.s %[temp5], %[temp3], %[temp4] \n\t"
"add.s %[temp8], %[temp6], %[temp7] \n\t"
"add.s %[temp11], %[temp9], %[temp10] \n\t"
"sub.s %[temp0], %[temp0], %[temp1] \n\t"
"sub.s %[temp3], %[temp3], %[temp4] \n\t"
"sub.s %[temp6], %[temp6], %[temp7] \n\t"
"sub.s %[temp9], %[temp9], %[temp10] \n\t"
"swc1 %[temp2], -32(%[v1]) \n\t"
"swc1 %[temp0], 32(%[v0]) \n\t"
"swc1 %[temp5], -36(%[v1]) \n\t"
"swc1 %[temp3], 36(%[v0]) \n\t"
"swc1 %[temp8], -40(%[v1]) \n\t"
"swc1 %[temp6], 40(%[v0]) \n\t"
"swc1 %[temp11], -44(%[v1]) \n\t"
"swc1 %[temp9], 44(%[v0]) \n\t"
"lwc1 %[temp0], 48(%[src0]) \n\t"
"lwc1 %[temp1], -48(%[src1]) \n\t"
"lwc1 %[temp3], 52(%[src0]) \n\t"
"lwc1 %[temp4], -52(%[src1]) \n\t"
"lwc1 %[temp6], 56(%[src0]) \n\t"
"lwc1 %[temp7], -56(%[src1]) \n\t"
"lwc1 %[temp9], 60(%[src0]) \n\t"
"lwc1 %[temp10], -60(%[src1]) \n\t"
"add.s %[temp2], %[temp0], %[temp1] \n\t"
"add.s %[temp5], %[temp3], %[temp4] \n\t"
"add.s %[temp8], %[temp6], %[temp7] \n\t"
"add.s %[temp11], %[temp9], %[temp10] \n\t"
"sub.s %[temp0], %[temp0], %[temp1] \n\t"
"sub.s %[temp3], %[temp3], %[temp4] \n\t"
"sub.s %[temp6], %[temp6], %[temp7] \n\t"
"sub.s %[temp9], %[temp9], %[temp10] \n\t"
"swc1 %[temp2], -48(%[v1]) \n\t"
"swc1 %[temp0], 48(%[v0]) \n\t"
"swc1 %[temp5], -52(%[v1]) \n\t"
"swc1 %[temp3], 52(%[v0]) \n\t"
"swc1 %[temp8], -56(%[v1]) \n\t"
"swc1 %[temp6], 56(%[v0]) \n\t"
"swc1 %[temp11], -60(%[v1]) \n\t"
"swc1 %[temp9], 60(%[v0]) \n\t"
PTR_ADDIU " %[src0], %[src0], 64 \n\t"
PTR_ADDIU " %[src1], %[src1], -64 \n\t"
PTR_ADDIU " %[v0], %[v0], 64 \n\t"
PTR_ADDIU " %[v1], %[v1], -64 \n\t"
: [v0]"+r"(v0), [v1]"+r"(v1), [src0]"+r"(psrc0), [src1]"+r"(psrc1),
[temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
:
:"memory"
);
}
}
static void sbr_autocorrelate_mips(const float x[40][2], float phi[3][2][2])
{
int i;
float real_sum_0 = 0.0f;
float real_sum_1 = 0.0f;
float real_sum_2 = 0.0f;
float imag_sum_1 = 0.0f;
float imag_sum_2 = 0.0f;
float *p_x, *p_phi;
float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
float temp7, temp_r, temp_r1, temp_r2, temp_r3, temp_r4;
p_x = (float*)&x[0][0];
p_phi = &phi[0][0][0];
__asm__ volatile (
"lwc1 %[temp0], 8(%[p_x]) \n\t"
"lwc1 %[temp1], 12(%[p_x]) \n\t"
"lwc1 %[temp2], 16(%[p_x]) \n\t"
"lwc1 %[temp3], 20(%[p_x]) \n\t"
"lwc1 %[temp4], 24(%[p_x]) \n\t"
"lwc1 %[temp5], 28(%[p_x]) \n\t"
"mul.s %[temp_r], %[temp1], %[temp1] \n\t"
"mul.s %[temp_r1], %[temp1], %[temp3] \n\t"
"mul.s %[temp_r2], %[temp1], %[temp2] \n\t"
"mul.s %[temp_r3], %[temp1], %[temp5] \n\t"
"mul.s %[temp_r4], %[temp1], %[temp4] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp0], %[temp0] \n\t"
"madd.s %[temp_r1], %[temp_r1], %[temp0], %[temp2] \n\t"
"msub.s %[temp_r2], %[temp_r2], %[temp0], %[temp3] \n\t"
"madd.s %[temp_r3], %[temp_r3], %[temp0], %[temp4] \n\t"
"msub.s %[temp_r4], %[temp_r4], %[temp0], %[temp5] \n\t"
"add.s %[real_sum_0], %[real_sum_0], %[temp_r] \n\t"
"add.s %[real_sum_1], %[real_sum_1], %[temp_r1] \n\t"
"add.s %[imag_sum_1], %[imag_sum_1], %[temp_r2] \n\t"
"add.s %[real_sum_2], %[real_sum_2], %[temp_r3] \n\t"
"add.s %[imag_sum_2], %[imag_sum_2], %[temp_r4] \n\t"
PTR_ADDIU "%[p_x], %[p_x], 8 \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
[imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
[temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1), [temp_r2]"=&f"(temp_r2),
[temp_r3]"=&f"(temp_r3), [temp_r4]"=&f"(temp_r4),
[p_x]"+r"(p_x), [imag_sum_2]"+f"(imag_sum_2)
:
: "memory"
);
for (i = 0; i < 12; i++) {
__asm__ volatile (
"lwc1 %[temp0], 8(%[p_x]) \n\t"
"lwc1 %[temp1], 12(%[p_x]) \n\t"
"lwc1 %[temp2], 16(%[p_x]) \n\t"
"lwc1 %[temp3], 20(%[p_x]) \n\t"
"lwc1 %[temp4], 24(%[p_x]) \n\t"
"lwc1 %[temp5], 28(%[p_x]) \n\t"
"mul.s %[temp_r], %[temp1], %[temp1] \n\t"
"mul.s %[temp_r1], %[temp1], %[temp3] \n\t"
"mul.s %[temp_r2], %[temp1], %[temp2] \n\t"
"mul.s %[temp_r3], %[temp1], %[temp5] \n\t"
"mul.s %[temp_r4], %[temp1], %[temp4] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp0], %[temp0] \n\t"
"madd.s %[temp_r1], %[temp_r1], %[temp0], %[temp2] \n\t"
"msub.s %[temp_r2], %[temp_r2], %[temp0], %[temp3] \n\t"
"madd.s %[temp_r3], %[temp_r3], %[temp0], %[temp4] \n\t"
"msub.s %[temp_r4], %[temp_r4], %[temp0], %[temp5] \n\t"
"add.s %[real_sum_0], %[real_sum_0], %[temp_r] \n\t"
"add.s %[real_sum_1], %[real_sum_1], %[temp_r1] \n\t"
"add.s %[imag_sum_1], %[imag_sum_1], %[temp_r2] \n\t"
"add.s %[real_sum_2], %[real_sum_2], %[temp_r3] \n\t"
"add.s %[imag_sum_2], %[imag_sum_2], %[temp_r4] \n\t"
"lwc1 %[temp0], 32(%[p_x]) \n\t"
"lwc1 %[temp1], 36(%[p_x]) \n\t"
"mul.s %[temp_r], %[temp3], %[temp3] \n\t"
"mul.s %[temp_r1], %[temp3], %[temp5] \n\t"
"mul.s %[temp_r2], %[temp3], %[temp4] \n\t"
"mul.s %[temp_r3], %[temp3], %[temp1] \n\t"
"mul.s %[temp_r4], %[temp3], %[temp0] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp2], %[temp2] \n\t"
"madd.s %[temp_r1], %[temp_r1], %[temp2], %[temp4] \n\t"
"msub.s %[temp_r2], %[temp_r2], %[temp2], %[temp5] \n\t"
"madd.s %[temp_r3], %[temp_r3], %[temp2], %[temp0] \n\t"
"msub.s %[temp_r4], %[temp_r4], %[temp2], %[temp1] \n\t"
"add.s %[real_sum_0], %[real_sum_0], %[temp_r] \n\t"
"add.s %[real_sum_1], %[real_sum_1], %[temp_r1] \n\t"
"add.s %[imag_sum_1], %[imag_sum_1], %[temp_r2] \n\t"
"add.s %[real_sum_2], %[real_sum_2], %[temp_r3] \n\t"
"add.s %[imag_sum_2], %[imag_sum_2], %[temp_r4] \n\t"
"lwc1 %[temp2], 40(%[p_x]) \n\t"
"lwc1 %[temp3], 44(%[p_x]) \n\t"
"mul.s %[temp_r], %[temp5], %[temp5] \n\t"
"mul.s %[temp_r1], %[temp5], %[temp1] \n\t"
"mul.s %[temp_r2], %[temp5], %[temp0] \n\t"
"mul.s %[temp_r3], %[temp5], %[temp3] \n\t"
"mul.s %[temp_r4], %[temp5], %[temp2] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp4], %[temp4] \n\t"
"madd.s %[temp_r1], %[temp_r1], %[temp4], %[temp0] \n\t"
"msub.s %[temp_r2], %[temp_r2], %[temp4], %[temp1] \n\t"
"madd.s %[temp_r3], %[temp_r3], %[temp4], %[temp2] \n\t"
"msub.s %[temp_r4], %[temp_r4], %[temp4], %[temp3] \n\t"
"add.s %[real_sum_0], %[real_sum_0], %[temp_r] \n\t"
"add.s %[real_sum_1], %[real_sum_1], %[temp_r1] \n\t"
"add.s %[imag_sum_1], %[imag_sum_1], %[temp_r2] \n\t"
"add.s %[real_sum_2], %[real_sum_2], %[temp_r3] \n\t"
"add.s %[imag_sum_2], %[imag_sum_2], %[temp_r4] \n\t"
PTR_ADDIU "%[p_x], %[p_x], 24 \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
[imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
[temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1),
[temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
[temp_r4]"=&f"(temp_r4), [p_x]"+r"(p_x),
[imag_sum_2]"+f"(imag_sum_2)
:
: "memory"
);
}
__asm__ volatile (
"lwc1 %[temp0], -296(%[p_x]) \n\t"
"lwc1 %[temp1], -292(%[p_x]) \n\t"
"lwc1 %[temp2], 8(%[p_x]) \n\t"
"lwc1 %[temp3], 12(%[p_x]) \n\t"
"lwc1 %[temp4], -288(%[p_x]) \n\t"
"lwc1 %[temp5], -284(%[p_x]) \n\t"
"lwc1 %[temp6], -280(%[p_x]) \n\t"
"lwc1 %[temp7], -276(%[p_x]) \n\t"
"madd.s %[temp_r], %[real_sum_0], %[temp0], %[temp0] \n\t"
"madd.s %[temp_r1], %[real_sum_0], %[temp2], %[temp2] \n\t"
"madd.s %[temp_r2], %[real_sum_1], %[temp0], %[temp4] \n\t"
"madd.s %[temp_r3], %[imag_sum_1], %[temp0], %[temp5] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp1], %[temp1] \n\t"
"madd.s %[temp_r1], %[temp_r1], %[temp3], %[temp3] \n\t"
"madd.s %[temp_r2], %[temp_r2], %[temp1], %[temp5] \n\t"
"nmsub.s %[temp_r3], %[temp_r3], %[temp1], %[temp4] \n\t"
"lwc1 %[temp4], 16(%[p_x]) \n\t"
"lwc1 %[temp5], 20(%[p_x]) \n\t"
"swc1 %[temp_r], 40(%[p_phi]) \n\t"
"swc1 %[temp_r1], 16(%[p_phi]) \n\t"
"swc1 %[temp_r2], 24(%[p_phi]) \n\t"
"swc1 %[temp_r3], 28(%[p_phi]) \n\t"
"madd.s %[temp_r], %[real_sum_1], %[temp2], %[temp4] \n\t"
"madd.s %[temp_r1], %[imag_sum_1], %[temp2], %[temp5] \n\t"
"madd.s %[temp_r2], %[real_sum_2], %[temp0], %[temp6] \n\t"
"madd.s %[temp_r3], %[imag_sum_2], %[temp0], %[temp7] \n\t"
"madd.s %[temp_r], %[temp_r], %[temp3], %[temp5] \n\t"
"nmsub.s %[temp_r1], %[temp_r1], %[temp3], %[temp4] \n\t"
"madd.s %[temp_r2], %[temp_r2], %[temp1], %[temp7] \n\t"
"nmsub.s %[temp_r3], %[temp_r3], %[temp1], %[temp6] \n\t"
"swc1 %[temp_r], 0(%[p_phi]) \n\t"
"swc1 %[temp_r1], 4(%[p_phi]) \n\t"
"swc1 %[temp_r2], 8(%[p_phi]) \n\t"
"swc1 %[temp_r3], 12(%[p_phi]) \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp_r]"=&f"(temp_r),
[real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
[real_sum_2]"+f"(real_sum_2), [imag_sum_1]"+f"(imag_sum_1),
[temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
[temp_r1]"=&f"(temp_r1), [p_phi]"+r"(p_phi),
[imag_sum_2]"+f"(imag_sum_2)
: [p_x]"r"(p_x)
: "memory"
);
}
static void sbr_hf_gen_mips(float (*X_high)[2], const float (*X_low)[2],
const float alpha0[2], const float alpha1[2],
float bw, int start, int end)
{
float alpha[4];
int i;
float *p_x_low = (float*)&X_low[0][0] + 2*start;
float *p_x_high = &X_high[0][0] + 2*start;
float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
float temp7, temp8, temp9, temp10, temp11, temp12;
alpha[0] = alpha1[0] * bw * bw;
alpha[1] = alpha1[1] * bw * bw;
alpha[2] = alpha0[0] * bw;
alpha[3] = alpha0[1] * bw;
for (i = start; i < end; i++) {
__asm__ volatile (
"lwc1 %[temp0], -16(%[p_x_low]) \n\t"
"lwc1 %[temp1], -12(%[p_x_low]) \n\t"
"lwc1 %[temp2], -8(%[p_x_low]) \n\t"
"lwc1 %[temp3], -4(%[p_x_low]) \n\t"
"lwc1 %[temp5], 0(%[p_x_low]) \n\t"
"lwc1 %[temp6], 4(%[p_x_low]) \n\t"
"lwc1 %[temp7], 0(%[alpha]) \n\t"
"lwc1 %[temp8], 4(%[alpha]) \n\t"
"lwc1 %[temp9], 8(%[alpha]) \n\t"
"lwc1 %[temp10], 12(%[alpha]) \n\t"
PTR_ADDIU "%[p_x_high], %[p_x_high], 8 \n\t"
PTR_ADDIU "%[p_x_low], %[p_x_low], 8 \n\t"
"mul.s %[temp11], %[temp1], %[temp8] \n\t"
"msub.s %[temp11], %[temp11], %[temp0], %[temp7] \n\t"
"madd.s %[temp11], %[temp11], %[temp2], %[temp9] \n\t"
"nmsub.s %[temp11], %[temp11], %[temp3], %[temp10] \n\t"
"add.s %[temp11], %[temp11], %[temp5] \n\t"
"swc1 %[temp11], -8(%[p_x_high]) \n\t"
"mul.s %[temp12], %[temp1], %[temp7] \n\t"
"madd.s %[temp12], %[temp12], %[temp0], %[temp8] \n\t"
"madd.s %[temp12], %[temp12], %[temp3], %[temp9] \n\t"
"madd.s %[temp12], %[temp12], %[temp2], %[temp10] \n\t"
"add.s %[temp12], %[temp12], %[temp6] \n\t"
"swc1 %[temp12], -4(%[p_x_high]) \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
[temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
[temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
[temp12]"=&f"(temp12), [p_x_high]"+r"(p_x_high),
[p_x_low]"+r"(p_x_low)
: [alpha]"r"(alpha)
: "memory"
);
}
}
static void sbr_hf_g_filt_mips(float (*Y)[2], const float (*X_high)[40][2],
const float *g_filt, int m_max, intptr_t ixh)
{
const float *p_x, *p_g, *loop_end;
float *p_y;
float temp0, temp1, temp2;
p_g = &g_filt[0];
p_y = &Y[0][0];
p_x = &X_high[0][ixh][0];
loop_end = p_g + m_max;
__asm__ volatile(
".set push \n\t"
".set noreorder \n\t"
"1: \n\t"
"lwc1 %[temp0], 0(%[p_g]) \n\t"
"lwc1 %[temp1], 0(%[p_x]) \n\t"
"lwc1 %[temp2], 4(%[p_x]) \n\t"
"mul.s %[temp1], %[temp1], %[temp0] \n\t"
"mul.s %[temp2], %[temp2], %[temp0] \n\t"
PTR_ADDIU "%[p_g], %[p_g], 4 \n\t"
PTR_ADDIU "%[p_x], %[p_x], 320 \n\t"
"swc1 %[temp1], 0(%[p_y]) \n\t"
"swc1 %[temp2], 4(%[p_y]) \n\t"
"bne %[p_g], %[loop_end], 1b \n\t"
PTR_ADDIU "%[p_y], %[p_y], 8 \n\t"
".set pop \n\t"
: [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
[temp2]"=&f"(temp2), [p_x]"+r"(p_x),
[p_y]"+r"(p_y), [p_g]"+r"(p_g)
: [loop_end]"r"(loop_end)
: "memory"
);
}
static void sbr_hf_apply_noise_0_mips(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
int kx, int m_max)
{
int m;
for (m = 0; m < m_max; m++){
float *Y1=&Y[m][0];
float *ff_table;
float y0,y1, temp1, temp2, temp4, temp5;
int temp0, temp3;
const float *s_m1=&s_m[m];
const float *q_filt1= &q_filt[m];
__asm__ volatile(
"lwc1 %[y0], 0(%[Y1]) \n\t"
"lwc1 %[temp1], 0(%[s_m1]) \n\t"
"addiu %[noise], %[noise], 1 \n\t"
"andi %[noise], %[noise], 0x1ff \n\t"
"sll %[temp0], %[noise], 3 \n\t"
PTR_ADDU "%[ff_table],%[ff_sbr_noise_table], %[temp0] \n\t"
"add.s %[y0], %[y0], %[temp1] \n\t"
"mfc1 %[temp3], %[temp1] \n\t"
"bne %[temp3], $0, 1f \n\t"
"lwc1 %[y1], 4(%[Y1]) \n\t"
"lwc1 %[temp2], 0(%[q_filt1]) \n\t"
"lwc1 %[temp4], 0(%[ff_table]) \n\t"
"lwc1 %[temp5], 4(%[ff_table]) \n\t"
"madd.s %[y0], %[y0], %[temp2], %[temp4] \n\t"
"madd.s %[y1], %[y1], %[temp2], %[temp5] \n\t"
"swc1 %[y1], 4(%[Y1]) \n\t"
"1: \n\t"
"swc1 %[y0], 0(%[Y1]) \n\t"
: [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
[temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
: [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
[Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
: "memory"
);
}
}
static void sbr_hf_apply_noise_1_mips(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
int kx, int m_max)
{
float y0,y1,temp1, temp2, temp4, temp5;
int temp0, temp3, m;
float phi_sign = 1 - 2 * (kx & 1);
for (m = 0; m < m_max; m++) {
float *ff_table;
float *Y1=&Y[m][0];
const float *s_m1=&s_m[m];
const float *q_filt1= &q_filt[m];
__asm__ volatile(
"lwc1 %[y1], 4(%[Y1]) \n\t"
"lwc1 %[temp1], 0(%[s_m1]) \n\t"
"lw %[temp3], 0(%[s_m1]) \n\t"
"addiu %[noise], %[noise], 1 \n\t"
"andi %[noise], %[noise], 0x1ff \n\t"
"sll %[temp0], %[noise], 3 \n\t"
PTR_ADDU "%[ff_table],%[ff_sbr_noise_table],%[temp0] \n\t"
"madd.s %[y1], %[y1], %[temp1], %[phi_sign] \n\t"
"bne %[temp3], $0, 1f \n\t"
"lwc1 %[y0], 0(%[Y1]) \n\t"
"lwc1 %[temp2], 0(%[q_filt1]) \n\t"
"lwc1 %[temp4], 0(%[ff_table]) \n\t"
"lwc1 %[temp5], 4(%[ff_table]) \n\t"
"madd.s %[y0], %[y0], %[temp2], %[temp4] \n\t"
"madd.s %[y1], %[y1], %[temp2], %[temp5] \n\t"
"swc1 %[y0], 0(%[Y1]) \n\t"
"1: \n\t"
"swc1 %[y1], 4(%[Y1]) \n\t"
: [ff_table] "=&r" (ff_table), [y0] "=&f" (y0), [y1] "=&f" (y1),
[temp0] "=&r" (temp0), [temp1] "=&f" (temp1), [temp2] "=&f" (temp2),
[temp3] "=&r" (temp3), [temp4] "=&f" (temp4), [temp5] "=&f" (temp5)
: [ff_sbr_noise_table] "r" (ff_sbr_noise_table), [noise] "r" (noise),
[Y1] "r" (Y1), [s_m1] "r" (s_m1), [q_filt1] "r" (q_filt1),
[phi_sign] "f" (phi_sign)
: "memory"
);
phi_sign = -phi_sign;
}
}
static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
int kx, int m_max)
{
int m;
float *ff_table;
float y0,y1, temp0, temp1, temp2, temp3, temp4, temp5;
for (m = 0; m < m_max; m++) {
float *Y1=&Y[m][0];
const float *s_m1=&s_m[m];
const float *q_filt1= &q_filt[m];
__asm__ volatile(
"lwc1 %[y0], 0(%[Y1]) \n\t"
"lwc1 %[temp1], 0(%[s_m1]) \n\t"
"addiu %[noise], %[noise], 1 \n\t"
"andi %[noise], %[noise], 0x1ff \n\t"
"sll %[temp0], %[noise], 3 \n\t"
PTR_ADDU "%[ff_table],%[ff_sbr_noise_table],%[temp0] \n\t"
"sub.s %[y0], %[y0], %[temp1] \n\t"
"mfc1 %[temp3], %[temp1] \n\t"
"bne %[temp3], $0, 1f \n\t"
"lwc1 %[y1], 4(%[Y1]) \n\t"
"lwc1 %[temp2], 0(%[q_filt1]) \n\t"
"lwc1 %[temp4], 0(%[ff_table]) \n\t"
"lwc1 %[temp5], 4(%[ff_table]) \n\t"
"madd.s %[y0], %[y0], %[temp2], %[temp4] \n\t"
"madd.s %[y1], %[y1], %[temp2], %[temp5] \n\t"
"swc1 %[y1], 4(%[Y1]) \n\t"
"1: \n\t"
"swc1 %[y0], 0(%[Y1]) \n\t"
: [temp0]"=&r"(temp0), [ff_table]"=&r"(ff_table), [y0]"=&f"(y0),
[y1]"=&f"(y1), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
: [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
[Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
: "memory"
);
}
}
static void sbr_hf_apply_noise_3_mips(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
int kx, int m_max)
{
float phi_sign = 1 - 2 * (kx & 1);
int m;
for (m = 0; m < m_max; m++) {
float *Y1=&Y[m][0];
float *ff_table;
float y0,y1, temp1, temp2, temp4, temp5;
int temp0, temp3;
const float *s_m1=&s_m[m];
const float *q_filt1= &q_filt[m];
__asm__ volatile(
"lwc1 %[y1], 4(%[Y1]) \n\t"
"lwc1 %[temp1], 0(%[s_m1]) \n\t"
"addiu %[noise], %[noise], 1 \n\t"
"andi %[noise], %[noise], 0x1ff \n\t"
"sll %[temp0], %[noise], 3 \n\t"
PTR_ADDU "%[ff_table],%[ff_sbr_noise_table], %[temp0] \n\t"
"nmsub.s %[y1], %[y1], %[temp1], %[phi_sign] \n\t"
"mfc1 %[temp3], %[temp1] \n\t"
"bne %[temp3], $0, 1f \n\t"
"lwc1 %[y0], 0(%[Y1]) \n\t"
"lwc1 %[temp2], 0(%[q_filt1]) \n\t"
"lwc1 %[temp4], 0(%[ff_table]) \n\t"
"lwc1 %[temp5], 4(%[ff_table]) \n\t"
"madd.s %[y0], %[y0], %[temp2], %[temp4] \n\t"
"madd.s %[y1], %[y1], %[temp2], %[temp5] \n\t"
"swc1 %[y0], 0(%[Y1]) \n\t"
"1: \n\t"
"swc1 %[y1], 4(%[Y1]) \n\t"
: [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
[temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
[temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
: [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
[Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1),
[phi_sign]"f"(phi_sign)
: "memory"
);
phi_sign = -phi_sign;
}
}
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
void ff_sbrdsp_init_mips(SBRDSPContext *s)
{
#if HAVE_INLINE_ASM
#if HAVE_MIPSFPU
s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_mips;
s->qmf_post_shuffle = sbr_qmf_post_shuffle_mips;
#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
s->sum64x5 = sbr_sum64x5_mips;
s->sum_square = sbr_sum_square_mips;
s->qmf_deint_bfly = sbr_qmf_deint_bfly_mips;
s->autocorrelate = sbr_autocorrelate_mips;
s->hf_gen = sbr_hf_gen_mips;
s->hf_g_filt = sbr_hf_g_filt_mips;
s->hf_apply_noise[0] = sbr_hf_apply_noise_0_mips;
s->hf_apply_noise[1] = sbr_hf_apply_noise_1_mips;
s->hf_apply_noise[2] = sbr_hf_apply_noise_2_mips;
s->hf_apply_noise[3] = sbr_hf_apply_noise_3_mips;
#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
#endif /* HAVE_MIPSFPU */
#endif /* HAVE_INLINE_ASM */
}

View File

@@ -0,0 +1,423 @@
/*
* Loongson SIMD optimized simple idct
*
* Copyright (c) 2015 Loongson Technology Corporation Limited
* Copyright (c) 2015 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
* Zhang Shuangshuang <zhangshuangshuang@ict.ac.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "idctdsp_mips.h"
#include "constants.h"
#include "libavutil/mips/asmdefs.h"
#include "libavutil/mips/mmiutils.h"
#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define ROW_SHIFT 11
#define COL_SHIFT 20
#define DC_SHIFT 3
DECLARE_ALIGNED(16, const int16_t, W_arr)[46] = {
W4, W2, W4, W6,
W1, W3, W5, W7,
W4, W6, -W4, -W2,
W3, -W7, -W1, -W5,
W4, -W6, -W4, W2,
W5, -W1, W7, W3,
W4, -W2, W4, -W6,
W7, -W5, W3, -W1,
1024, 0, 1024, 0, //ff_p32_1024 = 0x0000040000000400ULL
0, -1, -1, -1, //mask = 0xffffffffffff0000ULL
32, 32, 32, 32 //ff_p16_32 = 0x0020002000200020ULL
};
void ff_simple_idct_8_mmi(int16_t *block)
{
BACKUP_REG
__asm__ volatile (
#define IDCT_ROW_COND_DC(src1, src2) \
"dmfc1 $11, "#src1" \n\t" \
"dmfc1 $12, "#src2" \n\t" \
"and $11, $11, $9 \n\t" \
"or $10, $11, $12 \n\t" \
"beqz $10, 1f \n\t" \
\
"punpcklhw $f30, "#src1", "#src2" \n\t" \
"punpckhhw $f31, "#src1", "#src2" \n\t" \
/* s6, s4, s2, s0 */ \
"punpcklhw "#src1", $f30, $f31 \n\t" \
/* s7, s5, s3, s1 */ \
"punpckhhw "#src2", $f30, $f31 \n\t" \
\
"pmaddhw $f30, "#src1", $f18 \n\t" \
"pmaddhw $f31, "#src2", $f19 \n\t" \
"paddw $f28, $f30, $f31 \n\t" \
"psubw $f29, $f30, $f31 \n\t" \
"punpcklwd $f30, $f28, $f29 \n\t" \
"punpckhwd $f31, $f28, $f29 \n\t" \
"paddw $f26, $f30, $f31 \n\t" \
"paddw $f26, $f26, $f16 \n\t" \
/* $f26: src[7], src[0] */ \
"psraw $f26, $f26, $f17 \n\t" \
\
"pmaddhw $f30, "#src1", $f20 \n\t" \
"pmaddhw $f31, "#src2", $f21 \n\t" \
"paddw $f28, $f30, $f31 \n\t" \
"psubw $f29, $f30, $f31 \n\t" \
"punpcklwd $f30, $f28, $f29 \n\t" \
"punpckhwd $f31, $f28, $f29 \n\t" \
"paddw $f27, $f30, $f31 \n\t" \
"paddw $f27, $f27, $f16 \n\t" \
/* $f27: src[6], src[1] */ \
"psraw $f27, $f27, $f17 \n\t" \
\
"pmaddhw $f30, "#src1", $f22 \n\t" \
"pmaddhw $f31, "#src2", $f23 \n\t" \
"paddw $f28, $f30, $f31 \n\t" \
"psubw $f29, $f30, $f31 \n\t" \
"punpcklwd $f30, $f28, $f29 \n\t" \
"punpckhwd $f31, $f28, $f29 \n\t" \
"paddw $f28, $f30, $f31 \n\t" \
"paddw $f28, $f28, $f16 \n\t" \
/* $f28: src[5], src[2] */ \
"psraw $f28, $f28, $f17 \n\t" \
\
"pmaddhw $f30, "#src1", $f24 \n\t" \
"pmaddhw $f31, "#src2", $f25 \n\t" \
"paddw "#src1", $f30, $f31 \n\t" \
"psubw "#src2", $f30, $f31 \n\t" \
"punpcklwd $f30, "#src1", "#src2" \n\t" \
"punpckhwd $f31, "#src1", "#src2" \n\t" \
"paddw $f29, $f30, $f31 \n\t" \
"paddw $f29, $f29, $f16 \n\t" \
/* $f29: src[4], src[3] */ \
"psraw $f29, $f29, $f17 \n\t" \
\
"punpcklhw "#src1", $f26, $f27 \n\t" \
"punpckhhw $f30, $f27, $f26 \n\t" \
"punpcklhw $f31, $f28, $f29 \n\t" \
"punpckhhw "#src2", $f29, $f28 \n\t" \
/* src[3], src[2], src[1], src[0] */ \
"punpcklwd "#src1", "#src1", $f31 \n\t" \
/* src[7], src[6], src[5], src[4] */ \
"punpcklwd "#src2", "#src2", $f30 \n\t" \
"j 2f \n\t" \
\
"1: \n\t" \
"li $10, 3 \n\t" \
"dmtc1 $10, $f30 \n\t" \
"psllh $f28, "#src1", $f30 \n\t" \
"dmtc1 $9, $f31 \n\t" \
"punpcklhw $f29, $f28, $f28 \n\t" \
"and $f29, $f29, $f31 \n\t" \
"paddw $f28, $f28, $f29 \n\t" \
"punpcklwd "#src1", $f28, $f28 \n\t" \
"punpcklwd "#src2", $f28, $f28 \n\t" \
"2: \n\t" \
/* idctRowCondDC row0~8 */
/* load W */
"gslqc1 $f19, $f18, 0x00(%[w_arr]) \n\t"
"gslqc1 $f21, $f20, 0x10(%[w_arr]) \n\t"
"gslqc1 $f23, $f22, 0x20(%[w_arr]) \n\t"
"gslqc1 $f25, $f24, 0x30(%[w_arr]) \n\t"
"gslqc1 $f17, $f16, 0x40(%[w_arr]) \n\t"
/* load source in block */
"gslqc1 $f1, $f0, 0x00(%[block]) \n\t"
"gslqc1 $f3, $f2, 0x10(%[block]) \n\t"
"gslqc1 $f5, $f4, 0x20(%[block]) \n\t"
"gslqc1 $f7, $f6, 0x30(%[block]) \n\t"
"gslqc1 $f9, $f8, 0x40(%[block]) \n\t"
"gslqc1 $f11, $f10, 0x50(%[block]) \n\t"
"gslqc1 $f13, $f12, 0x60(%[block]) \n\t"
"gslqc1 $f15, $f14, 0x70(%[block]) \n\t"
/* $9: mask ; $f17: ROW_SHIFT */
"dmfc1 $9, $f17 \n\t"
"li $10, 11 \n\t"
"mtc1 $10, $f17 \n\t"
IDCT_ROW_COND_DC($f0,$f1)
IDCT_ROW_COND_DC($f2,$f3)
IDCT_ROW_COND_DC($f4,$f5)
IDCT_ROW_COND_DC($f6,$f7)
IDCT_ROW_COND_DC($f8,$f9)
IDCT_ROW_COND_DC($f10,$f11)
IDCT_ROW_COND_DC($f12,$f13)
IDCT_ROW_COND_DC($f14,$f15)
#define IDCT_COL_CASE1(src, out1, out2) \
"pmaddhw $f26, "#src", $f18 \n\t" \
"pmaddhw $f27, "#src", $f20 \n\t" \
"pmaddhw $f28, "#src", $f22 \n\t" \
"pmaddhw $f29, "#src", $f24 \n\t" \
\
"punpcklwd $f30, $f26, $f26 \n\t" \
"punpckhwd $f31, $f26, $f26 \n\t" \
/* $f26: src[0], src[56] */ \
"paddw $f26, $f30, $f31 \n\t" \
"punpcklwd $f30, $f27, $f27 \n\t" \
"punpckhwd $f31, $f27, $f27 \n\t" \
/* $f27: src[8], src[48] */ \
"paddw $f27, $f30, $f31 \n\t" \
"punpcklwd $f30, $f28, $f28 \n\t" \
"punpckhwd $f31, $f28, $f28 \n\t" \
/* $f28: src[16], src[40] */ \
"paddw $f28, $f30, $f31 \n\t" \
"punpcklwd $f30, $f29, $f29 \n\t" \
"punpckhwd $f31, $f29, $f29 \n\t" \
/* $f29: src[24], src[32] */ \
"paddw $f29, $f30, $f31 \n\t" \
\
/* out1: src[24], src[16], src[8], src[0] */ \
/* out2: src[56], src[48], src[40], src[32] */ \
"punpcklhw $f30, $f26, $f27 \n\t" \
"punpcklhw $f31, $f28, $f29 \n\t" \
"punpckhwd "#out1", $f30, $f31 \n\t" \
"psrah "#out1", "#out1", $f16 \n\t" \
"punpcklhw $f30, $f27, $f26 \n\t" \
"punpcklhw $f31, $f29, $f28 \n\t" \
"punpckhwd "#out2", $f31, $f30 \n\t" \
"psrah "#out2", "#out2", $f16 \n\t"
#define IDCT_COL_CASE2(src1, src2, out1, out2) \
"pmaddhw $f28, "#src1", $f18 \n\t" \
"pmaddhw $f29, "#src2", $f19 \n\t" \
"paddw $f30, $f28, $f29 \n\t" \
"psubw $f31, $f28, $f29 \n\t" \
"punpcklwd $f28, $f30, $f31 \n\t" \
"punpckhwd $f29, $f30, $f31 \n\t" \
"pmaddhw $f30, "#src1", $f20 \n\t" \
"pmaddhw $f31, "#src2", $f21 \n\t" \
/* $f26: src[0], src[56] */ \
"paddw $f26, $f28, $f29 \n\t" \
"paddw $f28, $f30, $f31 \n\t" \
"psubw $f29, $f30, $f31 \n\t" \
"punpcklwd $f30, $f28, $f29 \n\t" \
"punpckhwd $f31, $f28, $f29 \n\t" \
"pmaddhw $f28, "#src1", $f22 \n\t" \
"pmaddhw $f29, "#src2", $f23 \n\t" \
/* $f27: src[8], src[48] */ \
"paddw $f27, $f30, $f31 \n\t" \
"paddw $f30, $f28, $f29 \n\t" \
"psubw $f31, $f28, $f29 \n\t" \
"punpcklwd $f28, $f30, $f31 \n\t" \
"punpckhwd $f29, $f30, $f31 \n\t" \
"pmaddhw $f30, "#src1", $f24 \n\t" \
"pmaddhw $f31, "#src2", $f25 \n\t" \
/* $f28: src[16], src[40] */ \
"paddw $f28, $f28, $f29 \n\t" \
"paddw "#out1", $f30, $f31 \n\t" \
"psubw "#out2", $f30, $f31 \n\t" \
"punpcklwd $f30, "#out1", "#out2" \n\t" \
"punpckhwd $f31, "#out1", "#out2" \n\t" \
/* $f29: src[24], src[32] */ \
"paddw $f29, $f30, $f31 \n\t" \
\
/* out1: src[24], src[16], src[8], src[0] */ \
/* out2: src[56], src[48], src[40], src[32] */ \
"punpcklhw "#out1", $f26, $f27 \n\t" \
"punpckhhw "#out2", $f27, $f26 \n\t" \
"punpcklhw $f30, $f28, $f29 \n\t" \
"punpckhhw $f31, $f29, $f28 \n\t" \
"punpckhwd "#out1", "#out1", $f30 \n\t" \
"punpckhwd "#out2", $f31, "#out2" \n\t" \
"psrah "#out1", "#out1", $f16 \n\t" \
"psrah "#out2", "#out2", $f16 \n\t"
/* idctSparseCol col0~3 */
/* $f17: ff_p16_32; $f16: COL_SHIFT-16 */
"gsldlc1 $f17, 0x57(%[w_arr]) \n\t"
"gsldrc1 $f17, 0x50(%[w_arr]) \n\t"
"li $10, 4 \n\t"
"dmtc1 $10, $f16 \n\t"
"paddh $f0, $f0, $f17 \n\t"
/* Transpose row[0,2,4,6] */
"punpcklhw $f26, $f0, $f4 \n\t"
"punpckhhw $f27, $f0, $f4 \n\t"
"punpcklhw $f28, $f8, $f12 \n\t"
"punpckhhw $f29, $f8, $f12 \n\t"
"punpcklwd $f0, $f26, $f28 \n\t"
"punpckhwd $f4, $f26, $f28 \n\t"
"punpcklwd $f8, $f27, $f29 \n\t"
"punpckhwd $f12, $f27, $f29 \n\t"
"or $f26, $f2, $f6 \n\t"
"or $f26, $f26, $f10 \n\t"
"or $f26, $f26, $f14 \n\t"
"dmfc1 $10, $f26 \n\t"
"bnez $10, 1f \n\t"
/* case1: In this case, row[1,3,5,7] are all zero */
/* col0: $f0: col[24,16,8,0]; $f2: col[56,48,40,32] */
IDCT_COL_CASE1($f0, $f0, $f2)
/* col1: $f4: col[25,17,9,1]; $f6: col[57,49,41,33] */
IDCT_COL_CASE1($f4, $f4, $f6)
/* col2: $f8: col[26,18,10,2]; $f10: col[58,50,42,34] */
IDCT_COL_CASE1($f8, $f8, $f10)
/* col3: $f12: col[27,19,11,3]; $f14: col[59,51,43,35] */
IDCT_COL_CASE1($f12, $f12, $f14)
"j 2f \n\t"
"1: \n\t"
/* case2: row[1,3,5,7] are not all zero */
/* Transpose */
"punpcklhw $f26, $f2, $f6 \n\t"
"punpckhhw $f27, $f2, $f6 \n\t"
"punpcklhw $f28, $f10, $f14 \n\t"
"punpckhhw $f29, $f10, $f14 \n\t"
"punpcklwd $f2, $f26, $f28 \n\t"
"punpckhwd $f6, $f26, $f28 \n\t"
"punpcklwd $f10, $f27, $f29 \n\t"
"punpckhwd $f14, $f27, $f29 \n\t"
/* col0: $f0: col[24,16,8,0]; $f2: col[56,48,40,32] */
IDCT_COL_CASE2($f0, $f2, $f0, $f2)
/* col1: $f4: col[25,17,9,1]; $f6: col[57,49,41,33] */
IDCT_COL_CASE2($f4, $f6, $f4, $f6)
/* col2: $f8: col[26,18,10,2]; $f10: col[58,50,42,34] */
IDCT_COL_CASE2($f8, $f10, $f8, $f10)
/* col3: $f12: col[27,19,11,3]; $f14: col[59,51,43,35] */
IDCT_COL_CASE2($f12, $f14, $f12, $f14)
"2: \n\t"
/* Transpose */
"punpcklhw $f26, $f0, $f4 \n\t"
"punpckhhw $f27, $f0, $f4 \n\t"
"punpcklhw $f28, $f8, $f12 \n\t"
"punpckhhw $f29, $f8, $f12 \n\t"
"punpcklwd $f0, $f26, $f28 \n\t"
"punpckhwd $f4, $f26, $f28 \n\t"
"punpcklwd $f8, $f27, $f29 \n\t"
"punpckhwd $f12, $f27, $f29 \n\t"
/* Transpose */
"punpcklhw $f26, $f2, $f6 \n\t"
"punpckhhw $f27, $f2, $f6 \n\t"
"punpcklhw $f28, $f10, $f14 \n\t"
"punpckhhw $f29, $f10, $f14 \n\t"
"punpcklwd $f2, $f26, $f28 \n\t"
"punpckhwd $f6, $f26, $f28 \n\t"
"punpcklwd $f10, $f27, $f29 \n\t"
"punpckhwd $f14, $f27, $f29 \n\t"
/* idctSparseCol col4~7 */
"paddh $f1, $f1, $f17 \n\t"
/* Transpose */
"punpcklhw $f26, $f1, $f5 \n\t"
"punpckhhw $f27, $f1, $f5 \n\t"
"punpcklhw $f28, $f9, $f13 \n\t"
"punpckhhw $f29, $f9, $f13 \n\t"
"punpcklwd $f1, $f26, $f28 \n\t"
"punpckhwd $f5, $f26, $f28 \n\t"
"punpcklwd $f9, $f27, $f29 \n\t"
"punpckhwd $f13, $f27, $f29 \n\t"
"or $f26, $f3, $f7 \n\t"
"or $f26, $f26, $f11 \n\t"
"or $f26, $f26, $f15 \n\t"
"dmfc1 $10, $f26 \n\t"
"bnez $10, 1f \n\t"
/* case1: In this case, row[1,3,5,7] are all zero */
/* col4: $f1: col[24,16,8,0]; $f3: col[56,48,40,32] */
IDCT_COL_CASE1($f1, $f1, $f3)
/* col5: $f5: col[25,17,9,1]; $f7: col[57,49,41,33] */
IDCT_COL_CASE1($f5, $f5, $f7)
/* col6: $f9: col[26,18,10,2]; $f11: col[58,50,42,34] */
IDCT_COL_CASE1($f9, $f9, $f11)
/* col7: $f13: col[27,19,11,3]; $f15: col[59,51,43,35] */
IDCT_COL_CASE1($f13, $f13, $f15)
"j 2f \n\t"
"1: \n\t"
/* case2: row[1,3,5,7] are not all zero */
/* Transpose */
"punpcklhw $f26, $f3, $f7 \n\t"
"punpckhhw $f27, $f3, $f7 \n\t"
"punpcklhw $f28, $f11, $f15 \n\t"
"punpckhhw $f29, $f11, $f15 \n\t"
"punpcklwd $f3, $f26, $f28 \n\t"
"punpckhwd $f7, $f26, $f28 \n\t"
"punpcklwd $f11, $f27, $f29 \n\t"
"punpckhwd $f15, $f27, $f29 \n\t"
/* col4: $f1: col[24,16,8,0]; $f3: col[56,48,40,32] */
IDCT_COL_CASE2($f1, $f3, $f1, $f3)
/* col5: $f5: col[25,17,9,1]; $f7: col[57,49,41,33] */
IDCT_COL_CASE2($f5, $f7, $f5, $f7)
/* col6: $f9: col[26,18,10,2]; $f11: col[58,50,42,34] */
IDCT_COL_CASE2($f9, $f11, $f9, $f11)
/* col7: $f13: col[27,19,11,3]; $f15: col[59,51,43,35] */
IDCT_COL_CASE2($f13, $f15, $f13, $f15)
"2: \n\t"
/* Transpose */
"punpcklhw $f26, $f1, $f5 \n\t"
"punpckhhw $f27, $f1, $f5 \n\t"
"punpcklhw $f28, $f9, $f13 \n\t"
"punpckhhw $f29, $f9, $f13 \n\t"
"punpcklwd $f1, $f26, $f28 \n\t"
"punpckhwd $f5, $f26, $f28 \n\t"
"punpcklwd $f9, $f27, $f29 \n\t"
"punpckhwd $f13, $f27, $f29 \n\t"
/* Transpose */
"punpcklhw $f26, $f3, $f7 \n\t"
"punpckhhw $f27, $f3, $f7 \n\t"
"punpcklhw $f28, $f11, $f15 \n\t"
"punpckhhw $f29, $f11, $f15 \n\t"
"punpcklwd $f3, $f26, $f28 \n\t"
"punpckhwd $f7, $f26, $f28 \n\t"
"punpcklwd $f11, $f27, $f29 \n\t"
"punpckhwd $f15, $f27, $f29 \n\t"
/* Store */
"gssqc1 $f1, $f0, 0x00(%[block]) \n\t"
"gssqc1 $f5, $f4, 0x10(%[block]) \n\t"
"gssqc1 $f9, $f8, 0x20(%[block]) \n\t"
"gssqc1 $f13, $f12, 0x30(%[block]) \n\t"
"gssqc1 $f3, $f2, 0x40(%[block]) \n\t"
"gssqc1 $f7, $f6, 0x50(%[block]) \n\t"
"gssqc1 $f11, $f10, 0x60(%[block]) \n\t"
"gssqc1 $f15, $f14, 0x70(%[block]) \n\t"
: [block]"+&r"(block)
: [w_arr]"r"(W_arr)
: "memory"
);
RECOVER_REG
}
void ff_simple_idct_put_8_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
ff_simple_idct_8_mmi(block);
ff_put_pixels_clamped_mmi(block, dest, line_size);
}
void ff_simple_idct_add_8_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
ff_simple_idct_8_mmi(block);
ff_add_pixels_clamped_mmi(block, dest, line_size);
}

View File

@@ -0,0 +1,557 @@
/*
* Copyright (c) 2015 Parag Salasakar (Parag.Salasakar@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/mips/generic_macros_msa.h"
#include "idctdsp_mips.h"
static void simple_idct_msa(int16_t *block)
{
int32_t const_val;
v8i16 weights = { 0, 22725, 21407, 19266, 16383, 12873, 8867, 4520 };
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v8i16 w1, w3, w5, w7;
v8i16 const0, const1, const2, const3, const4, const5, const6, const7;
v4i32 temp0_r, temp1_r, temp2_r, temp3_r;
v4i32 temp0_l, temp1_l, temp2_l, temp3_l;
v4i32 a0_r, a1_r, a2_r, a3_r, a0_l, a1_l, a2_l, a3_l;
v4i32 b0_r, b1_r, b2_r, b3_r, b0_l, b1_l, b2_l, b3_l;
v4i32 w2, w4, w6;
v8i16 select_vec, temp;
v8i16 zero = { 0 };
v4i32 const_val0 = __msa_ldi_w(1);
v4i32 const_val1 = __msa_ldi_w(1);
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
const_val0 <<= 10;
const_val = 16383 * ((1 << 19) / 16383);
const_val1 = __msa_insert_w(const_val0, 0, const_val);
const_val1 = __msa_splati_w(const_val1, 0);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
select_vec = in1 | in2 | in3 | in4 | in5 | in6 | in7;
select_vec = __msa_clti_u_h((v8u16) select_vec, 1);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
temp = in0 << 3;
w2 = (v4i32) __msa_splati_h(weights, 2);
w2 = (v4i32) __msa_ilvr_h(zero, (v8i16) w2);
w4 = (v4i32) __msa_splati_h(weights, 4);
w4 = (v4i32) __msa_ilvr_h(zero, (v8i16) w4);
w6 = (v4i32) __msa_splati_h(weights, 6);
w6 = (v4i32) __msa_ilvr_h(zero, (v8i16) w6);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val0, a0_l, const_val0, temp0_r, temp0_l);
MUL4(w2, temp3_r, w2, temp3_l, w6, temp3_r, w6, temp3_l,
temp1_r, temp1_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
UNPCK_SH_SW(in4, temp0_r, temp0_l);
UNPCK_SH_SW(in6, temp3_r, temp3_l);
MUL2(temp0_r, w4, temp0_l, w4, temp0_r, temp0_l);
MUL4(w2, temp3_r, w2, temp3_l, w6, temp3_r, w6, temp3_l,
temp2_r, temp2_l, temp1_r, temp1_l);
ADD2(a0_r, temp0_r, a0_l, temp0_l, a0_r, a0_l);
SUB4(a1_r, temp0_r, a1_l, temp0_l, a2_r, temp0_r, a2_l, temp0_l,
a1_r, a1_l, a2_r, a2_l);
ADD4(a3_r, temp0_r, a3_l, temp0_l, a0_r, temp1_r, a0_l, temp1_l,
a3_r, a3_l, a0_r, a0_l);
SUB2(a1_r, temp2_r, a1_l, temp2_l, a1_r, a1_l);
ADD2(a2_r, temp2_r, a2_l, temp2_l, a2_r, a2_l);
SUB2(a3_r, temp1_r, a3_l, temp1_l, a3_r, a3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
SPLATI_H4_SH(weights, 1, 3, 5, 7, w1, w3, w5, w7);
ILVRL_H2_SW(in5, in7, temp0_r, temp0_l);
ILVR_H4_SH(w1, w3, w3, -w7, w5, -w1, w7, -w5,
const0, const1, const2, const3);
ILVR_H2_SH(w5, w7, w7, w3, const4, const6);
const5 = __msa_ilvod_h(-w1, -w5);
const7 = __msa_ilvod_h(w3, -w1);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp0_r, temp0_r, temp0_r, temp0_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
DPADD_SH4_SW(temp0_l, temp0_l, temp0_l, temp0_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 11);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 11);
PCKEV_H4_SW(temp0_l, temp0_r, temp1_l, temp1_r,
temp2_l, temp2_r, temp3_l, temp3_r,
temp0_r, temp1_r, temp2_r, temp3_r);
in0 = (v8i16) __msa_bmnz_v((v16u8) temp0_r, (v16u8) temp,
(v16u8) select_vec);
in1 = (v8i16) __msa_bmnz_v((v16u8) temp1_r, (v16u8) temp,
(v16u8) select_vec);
in2 = (v8i16) __msa_bmnz_v((v16u8) temp2_r, (v16u8) temp,
(v16u8) select_vec);
in3 = (v8i16) __msa_bmnz_v((v16u8) temp3_r, (v16u8) temp,
(v16u8) select_vec);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 11);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 11);
PCKEV_H4_SW(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
a0_r, a1_r, a2_r, a3_r);
in4 = (v8i16) __msa_bmnz_v((v16u8) a3_r, (v16u8) temp, (v16u8) select_vec);
in5 = (v8i16) __msa_bmnz_v((v16u8) a2_r, (v16u8) temp, (v16u8) select_vec);
in6 = (v8i16) __msa_bmnz_v((v16u8) a1_r, (v16u8) temp, (v16u8) select_vec);
in7 = (v8i16) __msa_bmnz_v((v16u8) a0_r, (v16u8) temp, (v16u8) select_vec);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
w2 = (v4i32) __msa_splati_h(weights, 2);
w2 = (v4i32) __msa_ilvr_h(zero, (v8i16) w2);
w4 = (v4i32) __msa_splati_h(weights, 4);
w4 = (v4i32) __msa_ilvr_h(zero, (v8i16) w4);
w6 = (v4i32) __msa_splati_h(weights, 6);
w6 = (v4i32) __msa_ilvr_h(zero, (v8i16) w6);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val1, a0_l, const_val1, temp0_r, temp0_l);
MUL4(w2, temp3_r, w2, temp3_l, w6, temp3_r, w6, temp3_l,
temp1_r, temp1_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
UNPCK_SH_SW(in4, temp0_r, temp0_l);
UNPCK_SH_SW(in6, temp3_r, temp3_l);
MUL2(temp0_r, w4, temp0_l, w4, temp0_r, temp0_l);
MUL4(w2, temp3_r, w2, temp3_l, w6, temp3_r, w6, temp3_l,
temp2_r, temp2_l, temp1_r, temp1_l);
ADD2(a0_r, temp0_r, a0_l, temp0_l, a0_r, a0_l);
SUB4(a1_r, temp0_r, a1_l, temp0_l, a2_r, temp0_r, a2_l, temp0_l,
a1_r, a1_l, a2_r, a2_l);
ADD4(a3_r, temp0_r, a3_l, temp0_l, a0_r, temp1_r, a0_l, temp1_l,
a3_r, a3_l, a0_r, a0_l);
SUB2(a1_r, temp2_r, a1_l, temp2_l, a1_r, a1_l);
ADD2(a2_r, temp2_r, a2_l, temp2_l, a2_r, a2_l);
SUB2(a3_r, temp1_r, a3_l, temp1_l, a3_r, a3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
SPLATI_H4_SH(weights, 1, 3, 5, 7, w1, w3, w5, w7);
ILVR_H4_SH(w1, w3, w3, -w7, w5, -w1, w7, -w5,
const0, const1, const2, const3);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
ILVRL_H2_SW(in5, in7, temp0_r, temp0_l);
ILVR_H2_SH(w5, w7, w7, w3, const4, const6);
const5 = __msa_ilvod_h(-w1, -w5);
const7 = __msa_ilvod_h(w3, -w1);
DPADD_SH4_SW(temp0_r, temp0_r, temp0_r, temp0_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp0_l, temp0_l, temp0_l, temp0_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 20);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 20);
PCKEV_H4_SW(temp0_l, temp0_r, temp1_l, temp1_r, temp2_l, temp2_r,
temp3_l, temp3_r, temp0_r, temp1_r, temp2_r, temp3_r);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 20);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 20);
PCKEV_H4_SW(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
a0_r, a1_r, a2_r, a3_r);
ST_SW8(temp0_r, temp1_r, temp2_r, temp3_r, a3_r, a2_r, a1_r, a0_r,
block, 8);
}
static void simple_idct_put_msa(uint8_t *dst, int32_t dst_stride,
int16_t *block)
{
int32_t const_val;
uint64_t tmp0, tmp1, tmp2, tmp3;
v8i16 weights = { 0, 22725, 21407, 19266, 16383, 12873, 8867, 4520 };
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v8i16 w1, w3, w5, w7;
v8i16 const0, const1, const2, const3, const4, const5, const6, const7;
v4i32 temp0_r, temp1_r, temp2_r, temp3_r;
v4i32 temp0_l, temp1_l, temp2_l, temp3_l;
v4i32 a0_r, a1_r, a2_r, a3_r, a0_l, a1_l, a2_l, a3_l;
v4i32 b0_r, b1_r, b2_r, b3_r, b0_l, b1_l, b2_l, b3_l;
v4i32 w2, w4, w6;
v8i16 select_vec, temp;
v8i16 zero = { 0 };
v4i32 const_val0 = __msa_ldi_w(1);
v4i32 const_val1 = __msa_ldi_w(1);
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
const_val0 <<= 10;
const_val = 16383 * ((1 << 19) / 16383);
const_val1 = __msa_insert_w(const_val0, 0, const_val);
const_val1 = __msa_splati_w(const_val1, 0);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
select_vec = in1 | in2 | in3 | in4 | in5 | in6 | in7;
select_vec = __msa_clti_u_h((v8u16) select_vec, 1);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
temp = in0 << 3;
w2 = (v4i32) __msa_splati_h(weights, 2);
w2 = (v4i32) __msa_ilvr_h(zero, (v8i16) w2);
w4 = (v4i32) __msa_splati_h(weights, 4);
w4 = (v4i32) __msa_ilvr_h(zero, (v8i16) w4);
w6 = (v4i32) __msa_splati_h(weights, 6);
w6 = (v4i32) __msa_ilvr_h(zero, (v8i16) w6);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val0, a0_l, const_val0, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp1_r, temp1_l);
MUL2(w6, temp3_r, w6, temp3_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
UNPCK_SH_SW(in4, temp0_r, temp0_l);
UNPCK_SH_SW(in6, temp3_r, temp3_l);
MUL2(temp0_r, w4, temp0_l, w4, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp2_r, temp2_l);
MUL2(w6, temp3_r, w6, temp3_l, temp1_r, temp1_l);
ADD2(a0_r, temp0_r, a0_l, temp0_l, a0_r, a0_l);
SUB2(a1_r, temp0_r, a1_l, temp0_l, a1_r, a1_l);
SUB2(a2_r, temp0_r, a2_l, temp0_l, a2_r, a2_l);
ADD2(a3_r, temp0_r, a3_l, temp0_l, a3_r, a3_l);
ADD2(a0_r, temp1_r, a0_l, temp1_l, a0_r, a0_l);
SUB2(a1_r, temp2_r, a1_l, temp2_l, a1_r, a1_l);
ADD2(a2_r, temp2_r, a2_l, temp2_l, a2_r, a2_l);
SUB2(a3_r, temp1_r, a3_l, temp1_l, a3_r, a3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
SPLATI_H4_SH(weights, 1, 3, 5, 7, w1, w3, w5, w7);
ILVRL_H2_SW(in5, in7, temp0_r, temp0_l);
ILVR_H4_SH(w1, w3, w3, -w7, w5, -w1, w7, -w5,
const0, const1, const2, const3);
ILVR_H2_SH(w5, w7, w7, w3, const4, const6);
const5 = __msa_ilvod_h(-w1, -w5);
const7 = __msa_ilvod_h(w3, -w1);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp0_r, temp0_r, temp0_r, temp0_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
DPADD_SH4_SW(temp0_l, temp0_l, temp0_l, temp0_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 11);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 11);
PCKEV_H4_SW(temp0_l, temp0_r, temp1_l, temp1_r,
temp2_l, temp2_r, temp3_l, temp3_r,
temp0_r, temp1_r, temp2_r, temp3_r);
in0 = (v8i16) __msa_bmnz_v((v16u8) temp0_r, (v16u8) temp,
(v16u8) select_vec);
in1 = (v8i16) __msa_bmnz_v((v16u8) temp1_r, (v16u8) temp,
(v16u8) select_vec);
in2 = (v8i16) __msa_bmnz_v((v16u8) temp2_r, (v16u8) temp,
(v16u8) select_vec);
in3 = (v8i16) __msa_bmnz_v((v16u8) temp3_r, (v16u8) temp,
(v16u8) select_vec);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 11);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 11);
PCKEV_H4_SW(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
a0_r, a1_r, a2_r, a3_r);
in4 = (v8i16) __msa_bmnz_v((v16u8) a3_r, (v16u8) temp, (v16u8) select_vec);
in5 = (v8i16) __msa_bmnz_v((v16u8) a2_r, (v16u8) temp, (v16u8) select_vec);
in6 = (v8i16) __msa_bmnz_v((v16u8) a1_r, (v16u8) temp, (v16u8) select_vec);
in7 = (v8i16) __msa_bmnz_v((v16u8) a0_r, (v16u8) temp, (v16u8) select_vec);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
w2 = (v4i32) __msa_splati_h(weights, 2);
w2 = (v4i32) __msa_ilvr_h(zero, (v8i16) w2);
w4 = (v4i32) __msa_splati_h(weights, 4);
w4 = (v4i32) __msa_ilvr_h(zero, (v8i16) w4);
w6 = (v4i32) __msa_splati_h(weights, 6);
w6 = (v4i32) __msa_ilvr_h(zero, (v8i16) w6);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val1, a0_l, const_val1, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp1_r, temp1_l);
MUL2(w6, temp3_r, w6, temp3_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
UNPCK_SH_SW(in4, temp0_r, temp0_l);
UNPCK_SH_SW(in6, temp3_r, temp3_l);
MUL2(temp0_r, w4, temp0_l, w4, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp2_r, temp2_l);
MUL2(w6, temp3_r, w6, temp3_l, temp1_r, temp1_l);
ADD2(a0_r, temp0_r, a0_l, temp0_l, a0_r, a0_l);
SUB2(a1_r, temp0_r, a1_l, temp0_l, a1_r, a1_l);
SUB2(a2_r, temp0_r, a2_l, temp0_l, a2_r, a2_l);
ADD2(a3_r, temp0_r, a3_l, temp0_l, a3_r, a3_l);
ADD2(a0_r, temp1_r, a0_l, temp1_l, a0_r, a0_l);
SUB2(a1_r, temp2_r, a1_l, temp2_l, a1_r, a1_l);
ADD2(a2_r, temp2_r, a2_l, temp2_l, a2_r, a2_l);
SUB2(a3_r, temp1_r, a3_l, temp1_l, a3_r, a3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
SPLATI_H4_SH(weights, 1, 3, 5, 7, w1, w3, w5, w7);
ILVR_H4_SH(w1, w3, w3, -w7, w5, -w1, w7, -w5,
const0, const1, const2, const3);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
ILVRL_H2_SW(in5, in7, temp0_r, temp0_l);
ILVR_H2_SH(w5, w7, w7, w3, const4, const6);
const5 = __msa_ilvod_h(-w1, -w5);
const7 = __msa_ilvod_h(w3, -w1);
DPADD_SH4_SW(temp0_r, temp0_r, temp0_r, temp0_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp0_l, temp0_l, temp0_l, temp0_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 20);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 20);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 20);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 20);
PCKEV_H4_SH(temp0_l, temp0_r, temp1_l, temp1_r, temp2_l, temp2_r,
temp3_l, temp3_r, in0, in1, in2, in3);
PCKEV_H4_SH(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
in4, in5, in6, in7);
CLIP_SH4_0_255(in0, in1, in2, in3);
PCKEV_B4_SH(in0, in0, in1, in1, in2, in2, in3, in3,
in0, in1, in2, in3);
tmp0 = __msa_copy_u_d((v2i64) in0, 1);
tmp1 = __msa_copy_u_d((v2i64) in1, 1);
tmp2 = __msa_copy_u_d((v2i64) in2, 1);
tmp3 = __msa_copy_u_d((v2i64) in3, 1);
SD4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride);
CLIP_SH4_0_255(in4, in5, in6, in7);
PCKEV_B4_SH(in4, in4, in5, in5, in6, in6, in7, in7,
in4, in5, in6, in7);
tmp3 = __msa_copy_u_d((v2i64) in4, 1);
tmp2 = __msa_copy_u_d((v2i64) in5, 1);
tmp1 = __msa_copy_u_d((v2i64) in6, 1);
tmp0 = __msa_copy_u_d((v2i64) in7, 1);
SD4(tmp0, tmp1, tmp2, tmp3, dst + 4 * dst_stride, dst_stride);
}
static void simple_idct_add_msa(uint8_t *dst, int32_t dst_stride,
int16_t *block)
{
int32_t const_val;
uint64_t tmp0, tmp1, tmp2, tmp3;
v8i16 weights = { 0, 22725, 21407, 19266, 16383, 12873, 8867, 4520 };
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v8i16 w1, w3, w5, w7;
v8i16 const0, const1, const2, const3, const4, const5, const6, const7;
v4i32 temp0_r, temp1_r, temp2_r, temp3_r;
v4i32 temp4_r, temp5_r, temp6_r, temp7_r, temp8_r;
v4i32 temp0_l, temp1_l, temp2_l, temp3_l;
v4i32 temp4_l, temp5_l, temp6_l, temp7_l, temp8_l;
v4i32 a0_r, a1_r, a2_r, a3_r, a0_l, a1_l, a2_l, a3_l;
v4i32 b0_r, b1_r, b2_r, b3_r, b0_l, b1_l, b2_l, b3_l;
v4i32 w2, w4, w6;
v8i16 select_vec, temp;
v8i16 zero = { 0 };
v4i32 const_val0 = __msa_ldi_w(1);
v4i32 const_val1 = __msa_ldi_w(1);
const_val0 <<= 10;
const_val = 16383 * ((1 << 19) / 16383);
const_val1 = __msa_insert_w(const_val0, 0, const_val);
const_val1 = __msa_splati_w(const_val1, 0);
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
select_vec = in1 | in2 | in3 | in4 | in5 | in6 | in7;
select_vec = __msa_clti_u_h((v8u16) select_vec, 1);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
UNPCK_SH_SW(in4, temp4_r, temp4_l);
UNPCK_SH_SW(in6, temp7_r, temp7_l);
ILVRL_H2_SW(in5, in7, temp8_r, temp8_l);
temp = in0 << 3;
SPLATI_H4_SH(weights, 1, 3, 5, 7, w1, w3, w5, w7);
ILVR_H4_SH(w1, w3, w3, -w7, w5, -w1, w7, -w5,
const0, const1, const2, const3);
ILVR_H2_SH(w5, w7, w7, w3, const4, const6);
const5 = __msa_ilvod_h(-w1, -w5);
const7 = __msa_ilvod_h(w3, -w1);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp8_r, temp8_r, temp8_r, temp8_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
DPADD_SH4_SW(temp8_l, temp8_l, temp8_l, temp8_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
w2 = (v4i32) __msa_splati_h(weights, 2);
w2 = (v4i32) __msa_ilvr_h(zero, (v8i16) w2);
w4 = (v4i32) __msa_splati_h(weights, 4);
w4 = (v4i32) __msa_ilvr_h(zero, (v8i16) w4);
w6 = (v4i32) __msa_splati_h(weights, 6);
w6 = (v4i32) __msa_ilvr_h(zero, (v8i16) w6);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val0, a0_l, const_val0, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp1_r, temp1_l);
MUL2(w6, temp3_r, w6, temp3_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
MUL2(temp4_r, w4, temp4_l, w4, temp4_r, temp4_l);
MUL2(temp7_r, w2, temp7_l, w2, temp6_r, temp6_l);
MUL2(temp7_r, w6, temp7_l, w6, temp5_r, temp5_l);
ADD2(a0_r, temp4_r, a0_l, temp4_l, a0_r, a0_l);
SUB2(a1_r, temp4_r, a1_l, temp4_l, a1_r, a1_l);
SUB2(a2_r, temp4_r, a2_l, temp4_l, a2_r, a2_l);
ADD2(a3_r, temp4_r, a3_l, temp4_l, a3_r, a3_l);
ADD2(a0_r, temp5_r, a0_l, temp5_l, a0_r, a0_l);
SUB2(a1_r, temp6_r, a1_l, temp6_l, a1_r, a1_l);
ADD2(a2_r, temp6_r, a2_l, temp6_l, a2_r, a2_l);
SUB2(a3_r, temp5_r, a3_l, temp5_l, a3_r, a3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 11);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 11);
PCKEV_H4_SW(temp0_l, temp0_r, temp1_l, temp1_r,
temp2_l, temp2_r, temp3_l, temp3_r,
temp0_r, temp1_r, temp2_r, temp3_r);
in0 = (v8i16) __msa_bmnz_v((v16u8) temp0_r, (v16u8) temp,
(v16u8) select_vec);
in1 = (v8i16) __msa_bmnz_v((v16u8) temp1_r, (v16u8) temp,
(v16u8) select_vec);
in2 = (v8i16) __msa_bmnz_v((v16u8) temp2_r, (v16u8) temp,
(v16u8) select_vec);
in3 = (v8i16) __msa_bmnz_v((v16u8) temp3_r, (v16u8) temp,
(v16u8) select_vec);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 11);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 11);
PCKEV_H4_SW(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
a0_r, a1_r, a2_r, a3_r);
in4 = (v8i16) __msa_bmnz_v((v16u8) a3_r, (v16u8) temp, (v16u8) select_vec);
in5 = (v8i16) __msa_bmnz_v((v16u8) a2_r, (v16u8) temp, (v16u8) select_vec);
in6 = (v8i16) __msa_bmnz_v((v16u8) a1_r, (v16u8) temp, (v16u8) select_vec);
in7 = (v8i16) __msa_bmnz_v((v16u8) a0_r, (v16u8) temp, (v16u8) select_vec);
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
in0, in1, in2, in3, in4, in5, in6, in7);
UNPCK_SH_SW(in0, a0_r, a0_l);
UNPCK_SH_SW(in2, temp3_r, temp3_l);
MUL2(a0_r, w4, a0_l, w4, a0_r, a0_l);
ADD2(a0_r, const_val1, a0_l, const_val1, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp1_r, temp1_l);
MUL2(w6, temp3_r, w6, temp3_l, temp2_r, temp2_l);
BUTTERFLY_8(temp0_r, temp0_l, temp0_r, temp0_l,
temp2_l, temp2_r, temp1_l, temp1_r,
a0_r, a0_l, a1_r, a1_l, a2_l, a2_r, a3_l, a3_r);
UNPCK_SH_SW(in4, temp0_r, temp0_l);
UNPCK_SH_SW(in6, temp3_r, temp3_l);
MUL2(temp0_r, w4, temp0_l, w4, temp0_r, temp0_l);
MUL2(w2, temp3_r, w2, temp3_l, temp2_r, temp2_l);
MUL2(w6, temp3_r, w6, temp3_l, temp1_r, temp1_l);
ADD2(a0_r, temp0_r, a0_l, temp0_l, a0_r, a0_l);
SUB2(a1_r, temp0_r, a1_l, temp0_l, a1_r, a1_l);
SUB2(a2_r, temp0_r, a2_l, temp0_l, a2_r, a2_l);
ADD2(a3_r, temp0_r, a3_l, temp0_l, a3_r, a3_l);
ADD2(a0_r, temp1_r, a0_l, temp1_l, a0_r, a0_l);
SUB2(a1_r, temp2_r, a1_l, temp2_l, a1_r, a1_l);
ADD2(a2_r, temp2_r, a2_l, temp2_l, a2_r, a2_l);
SUB2(a3_r, temp1_r, a3_l, temp1_l, a3_r, a3_l);
ILVRL_H2_SW(in1, in3, b3_r, b3_l);
ILVRL_H2_SW(in5, in7, temp0_r, temp0_l);
DOTP_SH4_SW(b3_r, b3_r, b3_r, b3_r, const0, const1, const2, const3,
b0_r, b1_r, b2_r, b3_r);
DOTP_SH4_SW(b3_l, b3_l, b3_l, b3_l, const0, const1, const2, const3,
b0_l, b1_l, b2_l, b3_l);
DPADD_SH4_SW(temp0_r, temp0_r, temp0_r, temp0_r,
const4, const5, const6, const7, b0_r, b1_r, b2_r, b3_r);
DPADD_SH4_SW(temp0_l, temp0_l, temp0_l, temp0_l,
const4, const5, const6, const7, b0_l, b1_l, b2_l, b3_l);
BUTTERFLY_16(a0_r, a0_l, a1_r, a1_l, a2_r, a2_l, a3_r, a3_l,
b3_l, b3_r, b2_l, b2_r, b1_l, b1_r, b0_l, b0_r,
temp0_r, temp0_l, temp1_r, temp1_l,
temp2_r, temp2_l, temp3_r, temp3_l,
a3_l, a3_r, a2_l, a2_r, a1_l, a1_r, a0_l, a0_r);
SRA_4V(temp0_r, temp0_l, temp1_r, temp1_l, 20);
SRA_4V(temp2_r, temp2_l, temp3_r, temp3_l, 20);
LD_SH4(dst, dst_stride, in0, in1, in2, in3);
PCKEV_H4_SW(temp0_l, temp0_r, temp1_l, temp1_r, temp2_l, temp2_r,
temp3_l, temp3_r, temp0_r, temp1_r, temp2_r, temp3_r);
ILVR_B4_SW(zero, in0, zero, in1, zero, in2, zero, in3,
temp0_l, temp1_l, temp2_l, temp3_l);
in0 = (v8i16) (temp0_r) + (v8i16) (temp0_l);
in1 = (v8i16) (temp1_r) + (v8i16) (temp1_l);
in2 = (v8i16) (temp2_r) + (v8i16) (temp2_l);
in3 = (v8i16) (temp3_r) + (v8i16) (temp3_l);
CLIP_SH4_0_255(in0, in1, in2, in3);
PCKEV_B4_SH(in0, in0, in1, in1, in2, in2, in3, in3,
in0, in1, in2, in3);
tmp0 = __msa_copy_u_d((v2i64) in0, 1);
tmp1 = __msa_copy_u_d((v2i64) in1, 1);
tmp2 = __msa_copy_u_d((v2i64) in2, 1);
tmp3 = __msa_copy_u_d((v2i64) in3, 1);
SD4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride);
SRA_4V(a3_r, a3_l, a2_r, a2_l, 20);
SRA_4V(a1_r, a1_l, a0_r, a0_l, 20);
LD_SH4(dst + 4 * dst_stride, dst_stride, in4, in5, in6, in7);
PCKEV_H4_SW(a0_l, a0_r, a1_l, a1_r, a2_l, a2_r, a3_l, a3_r,
a0_r, a1_r, a2_r, a3_r);
ILVR_B4_SW(zero, in4, zero, in5, zero, in6, zero, in7,
a3_l, a2_l, a1_l, a0_l);
in4 = (v8i16) (a3_r) + (v8i16) (a3_l);
in5 = (v8i16) (a2_r) + (v8i16) (a2_l);
in6 = (v8i16) (a1_r) + (v8i16) (a1_l);
in7 = (v8i16) (a0_r) + (v8i16) (a0_l);
CLIP_SH4_0_255(in4, in5, in6, in7);
PCKEV_B4_SH(in4, in4, in5, in5, in6, in6, in7, in7,
in4, in5, in6, in7);
tmp0 = __msa_copy_u_d((v2i64) in4, 1);
tmp1 = __msa_copy_u_d((v2i64) in5, 1);
tmp2 = __msa_copy_u_d((v2i64) in6, 1);
tmp3 = __msa_copy_u_d((v2i64) in7, 1);
SD4(tmp0, tmp1, tmp2, tmp3, dst + 4 * dst_stride, dst_stride);
}
void ff_simple_idct_msa(int16_t *block)
{
simple_idct_msa(block);
}
void ff_simple_idct_put_msa(uint8_t *dst, ptrdiff_t dst_stride, int16_t *block)
{
simple_idct_put_msa(dst, dst_stride, block);
}
void ff_simple_idct_add_msa(uint8_t *dst, ptrdiff_t dst_stride, int16_t *block)
{
simple_idct_add_msa(dst, dst_stride, block);
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavcodec/vc1dsp.h"
#include "vc1dsp_mips.h"
#include "config.h"
#define FN_ASSIGN(OP, X, Y, INSN) \
dsp->OP##vc1_mspel_pixels_tab[1][X+4*Y] = ff_##OP##vc1_mspel_mc##X##Y##INSN; \
dsp->OP##vc1_mspel_pixels_tab[0][X+4*Y] = ff_##OP##vc1_mspel_mc##X##Y##_16##INSN
#if HAVE_MMI
static av_cold void vc1dsp_init_mmi(VC1DSPContext *dsp)
{
#if _MIPS_SIM != _ABIO32
dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_mmi;
dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_mmi;
dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_mmi;
#endif
dsp->vc1_inv_trans_4x4 = ff_vc1_inv_trans_4x4_mmi;
dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmi;
dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmi;
dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmi;
dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmi;
dsp->vc1_h_overlap = ff_vc1_h_overlap_mmi;
dsp->vc1_v_overlap = ff_vc1_v_overlap_mmi;
dsp->vc1_h_s_overlap = ff_vc1_h_s_overlap_mmi;
dsp->vc1_v_s_overlap = ff_vc1_v_s_overlap_mmi;
dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_mmi;
dsp->vc1_h_loop_filter4 = ff_vc1_h_loop_filter4_mmi;
dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_mmi;
dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_mmi;
dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_mmi;
dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_mmi;
FN_ASSIGN(put_, 0, 0, _mmi);
FN_ASSIGN(put_, 0, 1, _mmi);
FN_ASSIGN(put_, 0, 2, _mmi);
FN_ASSIGN(put_, 0, 3, _mmi);
FN_ASSIGN(put_, 1, 0, _mmi);
//FN_ASSIGN(put_, 1, 1, _mmi);//FIXME
//FN_ASSIGN(put_, 1, 2, _mmi);//FIXME
//FN_ASSIGN(put_, 1, 3, _mmi);//FIXME
FN_ASSIGN(put_, 2, 0, _mmi);
//FN_ASSIGN(put_, 2, 1, _mmi);//FIXME
//FN_ASSIGN(put_, 2, 2, _mmi);//FIXME
//FN_ASSIGN(put_, 2, 3, _mmi);//FIXME
FN_ASSIGN(put_, 3, 0, _mmi);
//FN_ASSIGN(put_, 3, 1, _mmi);//FIXME
//FN_ASSIGN(put_, 3, 2, _mmi);//FIXME
//FN_ASSIGN(put_, 3, 3, _mmi);//FIXME
FN_ASSIGN(avg_, 0, 0, _mmi);
FN_ASSIGN(avg_, 0, 1, _mmi);
FN_ASSIGN(avg_, 0, 2, _mmi);
FN_ASSIGN(avg_, 0, 3, _mmi);
FN_ASSIGN(avg_, 1, 0, _mmi);
//FN_ASSIGN(avg_, 1, 1, _mmi);//FIXME
//FN_ASSIGN(avg_, 1, 2, _mmi);//FIXME
//FN_ASSIGN(avg_, 1, 3, _mmi);//FIXME
FN_ASSIGN(avg_, 2, 0, _mmi);
//FN_ASSIGN(avg_, 2, 1, _mmi);//FIXME
//FN_ASSIGN(avg_, 2, 2, _mmi);//FIXME
//FN_ASSIGN(avg_, 2, 3, _mmi);//FIXME
FN_ASSIGN(avg_, 3, 0, _mmi);
//FN_ASSIGN(avg_, 3, 1, _mmi);//FIXME
//FN_ASSIGN(avg_, 3, 2, _mmi);//FIXME
//FN_ASSIGN(avg_, 3, 3, _mmi);//FIXME
dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_no_rnd_vc1_chroma_mc8_mmi;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_no_rnd_vc1_chroma_mc8_mmi;
dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_no_rnd_vc1_chroma_mc4_mmi;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_no_rnd_vc1_chroma_mc4_mmi;
}
#endif /* HAVE_MMI */
#if HAVE_MSA
static av_cold void vc1dsp_init_msa(VC1DSPContext *dsp)
{
dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_msa;
dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_msa;
dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_msa;
FN_ASSIGN(put_, 1, 1, _msa);
FN_ASSIGN(put_, 1, 2, _msa);
FN_ASSIGN(put_, 1, 3, _msa);
FN_ASSIGN(put_, 2, 1, _msa);
FN_ASSIGN(put_, 2, 2, _msa);
FN_ASSIGN(put_, 2, 3, _msa);
FN_ASSIGN(put_, 3, 1, _msa);
FN_ASSIGN(put_, 3, 2, _msa);
FN_ASSIGN(put_, 3, 3, _msa);
}
#endif /* HAVE_MSA */
av_cold void ff_vc1dsp_init_mips(VC1DSPContext *dsp)
{
#if HAVE_MMI
vc1dsp_init_mmi(dsp);
#endif /* HAVE_MMI */
#if HAVE_MSA
vc1dsp_init_msa(dsp);
#endif /* HAVE_MSA */
}

217
externals/ffmpeg/libavcodec/mips/vc1dsp_mips.h vendored Executable file
View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_VC1DSP_MIPS_H
#define AVCODEC_MIPS_VC1DSP_MIPS_H
#include "libavcodec/vc1dsp.h"
void ff_put_vc1_mspel_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc00_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc01_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc02_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc03_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc10_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc11_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc12_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc13_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc20_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc21_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc22_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc23_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc30_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc31_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc32_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc33_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc00_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc01_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc02_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc03_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc10_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc11_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc12_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc13_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc20_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc21_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc22_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc23_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc30_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc31_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc32_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_put_vc1_mspel_mc33_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc00_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc01_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc02_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc03_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc10_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc11_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc12_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc13_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc20_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc21_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc22_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc23_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc30_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc31_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc32_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_avg_vc1_mspel_mc33_16_mmi(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int rnd);
void ff_vc1_inv_trans_8x8_mmi(int16_t block[64]);
void ff_vc1_inv_trans_8x4_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_4x8_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_4x4_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_4x4_dc_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_4x8_dc_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_8x4_dc_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_8x8_dc_mmi(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_v_overlap_mmi(uint8_t *src, int stride);
void ff_vc1_h_overlap_mmi(uint8_t *src, int stride);
void ff_vc1_v_s_overlap_mmi(int16_t *top, int16_t *bottom);
void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right, int left_stride, int right_stride, int flags);
void ff_vc1_v_loop_filter4_mmi(uint8_t *src, int stride, int pq);
void ff_vc1_h_loop_filter4_mmi(uint8_t *src, int stride, int pq);
void ff_vc1_v_loop_filter8_mmi(uint8_t *src, int stride, int pq);
void ff_vc1_h_loop_filter8_mmi(uint8_t *src, int stride, int pq);
void ff_vc1_v_loop_filter16_mmi(uint8_t *src, int stride, int pq);
void ff_vc1_h_loop_filter16_mmi(uint8_t *src, int stride, int pq);
void ff_put_no_rnd_vc1_chroma_mc8_mmi(uint8_t *dst /* align 8 */,
uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y);
void ff_put_no_rnd_vc1_chroma_mc4_mmi(uint8_t *dst /* align 8 */,
uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y);
void ff_avg_no_rnd_vc1_chroma_mc8_mmi(uint8_t *dst /* align 8 */,
uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y);
void ff_avg_no_rnd_vc1_chroma_mc4_mmi(uint8_t *dst /* align 8 */,
uint8_t *src /* align 1 */,
ptrdiff_t stride, int h, int x, int y);
void ff_vc1_inv_trans_8x8_msa(int16_t block[64]);
void ff_vc1_inv_trans_8x4_msa(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
void ff_vc1_inv_trans_4x8_msa(uint8_t *dest, ptrdiff_t linesize, int16_t *block);
#define FF_PUT_VC1_MSPEL_MC_MSA(hmode, vmode) \
void ff_put_vc1_mspel_mc ## hmode ## vmode ## _msa(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t stride, int rnd); \
void ff_put_vc1_mspel_mc ## hmode ## vmode ## _16_msa(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t stride, int rnd);
FF_PUT_VC1_MSPEL_MC_MSA(1, 1);
FF_PUT_VC1_MSPEL_MC_MSA(1, 2);
FF_PUT_VC1_MSPEL_MC_MSA(1, 3);
FF_PUT_VC1_MSPEL_MC_MSA(2, 1);
FF_PUT_VC1_MSPEL_MC_MSA(2, 2);
FF_PUT_VC1_MSPEL_MC_MSA(2, 3);
FF_PUT_VC1_MSPEL_MC_MSA(3, 1);
FF_PUT_VC1_MSPEL_MC_MSA(3, 2);
FF_PUT_VC1_MSPEL_MC_MSA(3, 3);
#endif /* AVCODEC_MIPS_VC1DSP_MIPS_H */

2462
externals/ffmpeg/libavcodec/mips/vc1dsp_mmi.c vendored Executable file

File diff suppressed because it is too large Load Diff

461
externals/ffmpeg/libavcodec/mips/vc1dsp_msa.c vendored Executable file
View File

@@ -0,0 +1,461 @@
/*
* Loongson SIMD optimized vc1dsp
*
* Copyright (c) 2019 Loongson Technology Corporation Limited
* gxw <guxiwei-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vc1dsp_mips.h"
#include "constants.h"
#include "libavutil/mips/generic_macros_msa.h"
void ff_vc1_inv_trans_8x8_msa(int16_t block[64])
{
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v4i32 in_r0, in_r1, in_r2, in_r3, in_r4, in_r5, in_r6, in_r7;
v4i32 in_l0, in_l1, in_l2, in_l3, in_l4, in_l5, in_l6, in_l7;
v4i32 t_r1, t_r2, t_r3, t_r4, t_r5, t_r6, t_r7, t_r8;
v4i32 t_l1, t_l2, t_l3, t_l4, t_l5, t_l6, t_l7, t_l8;
v4i32 cnst_12 = {12, 12, 12, 12};
v4i32 cnst_4 = {4, 4, 4, 4};
v4i32 cnst_16 = {16, 16, 16, 16};
v4i32 cnst_6 = {6, 6, 6, 6};
v4i32 cnst_15 = {15, 15, 15, 15};
v4i32 cnst_9 = {9, 9, 9, 9};
v4i32 cnst_1 = {1, 1, 1, 1};
v4i32 cnst_64 = {64, 64, 64, 64};
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
UNPCK_SH_SW(in0, in_r0, in_l0);
UNPCK_SH_SW(in1, in_r1, in_l1);
UNPCK_SH_SW(in2, in_r2, in_l2);
UNPCK_SH_SW(in3, in_r3, in_l3);
UNPCK_SH_SW(in4, in_r4, in_l4);
UNPCK_SH_SW(in5, in_r5, in_l5);
UNPCK_SH_SW(in6, in_r6, in_l6);
UNPCK_SH_SW(in7, in_r7, in_l7);
// First loop
t_r1 = cnst_12 * (in_r0 + in_r4) + cnst_4;
t_l1 = cnst_12 * (in_l0 + in_l4) + cnst_4;
t_r2 = cnst_12 * (in_r0 - in_r4) + cnst_4;
t_l2 = cnst_12 * (in_l0 - in_l4) + cnst_4;
t_r3 = cnst_16 * in_r2 + cnst_6 * in_r6;
t_l3 = cnst_16 * in_l2 + cnst_6 * in_l6;
t_r4 = cnst_6 * in_r2 - cnst_16 * in_r6;
t_l4 = cnst_6 * in_l2 - cnst_16 * in_l6;
ADD4(t_r1, t_r3, t_l1, t_l3, t_r2, t_r4, t_l2, t_l4, t_r5, t_l5, t_r6, t_l6);
SUB4(t_r2, t_r4, t_l2, t_l4, t_r1, t_r3, t_l1, t_l3, t_r7, t_l7, t_r8, t_l8);
t_r1 = cnst_16 * in_r1 + cnst_15 * in_r3 + cnst_9 * in_r5 + cnst_4 * in_r7;
t_l1 = cnst_16 * in_l1 + cnst_15 * in_l3 + cnst_9 * in_l5 + cnst_4 * in_l7;
t_r2 = cnst_15 * in_r1 - cnst_4 * in_r3 - cnst_16 * in_r5 - cnst_9 * in_r7;
t_l2 = cnst_15 * in_l1 - cnst_4 * in_l3 - cnst_16 * in_l5 - cnst_9 * in_l7;
t_r3 = cnst_9 * in_r1 - cnst_16 * in_r3 + cnst_4 * in_r5 + cnst_15 * in_r7;
t_l3 = cnst_9 * in_l1 - cnst_16 * in_l3 + cnst_4 * in_l5 + cnst_15 * in_l7;
t_r4 = cnst_4 * in_r1 - cnst_9 * in_r3 + cnst_15 * in_r5 - cnst_16 * in_r7;
t_l4 = cnst_4 * in_l1 - cnst_9 * in_l3 + cnst_15 * in_l5 - cnst_16 * in_l7;
in_r0 = (t_r5 + t_r1) >> 3;
in_l0 = (t_l5 + t_l1) >> 3;
in_r1 = (t_r6 + t_r2) >> 3;
in_l1 = (t_l6 + t_l2) >> 3;
in_r2 = (t_r7 + t_r3) >> 3;
in_l2 = (t_l7 + t_l3) >> 3;
in_r3 = (t_r8 + t_r4) >> 3;
in_l3 = (t_l8 + t_l4) >> 3;
in_r4 = (t_r8 - t_r4) >> 3;
in_l4 = (t_l8 - t_l4) >> 3;
in_r5 = (t_r7 - t_r3) >> 3;
in_l5 = (t_l7 - t_l3) >> 3;
in_r6 = (t_r6 - t_r2) >> 3;
in_l6 = (t_l6 - t_l2) >> 3;
in_r7 = (t_r5 - t_r1) >> 3;
in_l7 = (t_l5 - t_l1) >> 3;
TRANSPOSE4x4_SW_SW(in_r0, in_r1, in_r2, in_r3, in_r0, in_r1, in_r2, in_r3);
TRANSPOSE4x4_SW_SW(in_l0, in_l1, in_l2, in_l3, in_l0, in_l1, in_l2, in_l3);
TRANSPOSE4x4_SW_SW(in_r4, in_r5, in_r6, in_r7, in_r4, in_r5, in_r6, in_r7);
TRANSPOSE4x4_SW_SW(in_l4, in_l5, in_l6, in_l7, in_l4, in_l5, in_l6, in_l7);
// Second loop
t_r1 = cnst_12 * (in_r0 + in_l0) + cnst_64;
t_l1 = cnst_12 * (in_r4 + in_l4) + cnst_64;
t_r2 = cnst_12 * (in_r0 - in_l0) + cnst_64;
t_l2 = cnst_12 * (in_r4 - in_l4) + cnst_64;
t_r3 = cnst_16 * in_r2 + cnst_6 * in_l2;
t_l3 = cnst_16 * in_r6 + cnst_6 * in_l6;
t_r4 = cnst_6 * in_r2 - cnst_16 * in_l2;
t_l4 = cnst_6 * in_r6 - cnst_16 * in_l6;
ADD4(t_r1, t_r3, t_l1, t_l3, t_r2, t_r4, t_l2, t_l4, t_r5, t_l5, t_r6, t_l6);
SUB4(t_r2, t_r4, t_l2, t_l4, t_r1, t_r3, t_l1, t_l3, t_r7, t_l7, t_r8, t_l8);
t_r1 = cnst_16 * in_r1 + cnst_15 * in_r3 + cnst_9 * in_l1 + cnst_4 * in_l3;
t_l1 = cnst_16 * in_r5 + cnst_15 * in_r7 + cnst_9 * in_l5 + cnst_4 * in_l7;
t_r2 = cnst_15 * in_r1 - cnst_4 * in_r3 - cnst_16 * in_l1 - cnst_9 * in_l3;
t_l2 = cnst_15 * in_r5 - cnst_4 * in_r7 - cnst_16 * in_l5 - cnst_9 * in_l7;
t_r3 = cnst_9 * in_r1 - cnst_16 * in_r3 + cnst_4 * in_l1 + cnst_15 * in_l3;
t_l3 = cnst_9 * in_r5 - cnst_16 * in_r7 + cnst_4 * in_l5 + cnst_15 * in_l7;
t_r4 = cnst_4 * in_r1 - cnst_9 * in_r3 + cnst_15 * in_l1 - cnst_16 * in_l3;
t_l4 = cnst_4 * in_r5 - cnst_9 * in_r7 + cnst_15 * in_l5 - cnst_16 * in_l7;
in_r0 = (t_r5 + t_r1) >> 7;
in_l0 = (t_l5 + t_l1) >> 7;
in_r1 = (t_r6 + t_r2) >> 7;
in_l1 = (t_l6 + t_l2) >> 7;
in_r2 = (t_r7 + t_r3) >> 7;
in_l2 = (t_l7 + t_l3) >> 7;
in_r3 = (t_r8 + t_r4) >> 7;
in_l3 = (t_l8 + t_l4) >> 7;
in_r4 = (t_r8 - t_r4 + cnst_1) >> 7;
in_l4 = (t_l8 - t_l4 + cnst_1) >> 7;
in_r5 = (t_r7 - t_r3 + cnst_1) >> 7;
in_l5 = (t_l7 - t_l3 + cnst_1) >> 7;
in_r6 = (t_r6 - t_r2 + cnst_1) >> 7;
in_l6 = (t_l6 - t_l2 + cnst_1) >> 7;
in_r7 = (t_r5 - t_r1 + cnst_1) >> 7;
in_l7 = (t_l5 - t_l1 + cnst_1) >> 7;
PCKEV_H4_SH(in_l0, in_r0, in_l1, in_r1, in_l2, in_r2, in_l3, in_r3,
in0, in1, in2, in3);
PCKEV_H4_SH(in_l4, in_r4, in_l5, in_r5, in_l6, in_r6, in_l7, in_r7,
in4, in5, in6, in7);
ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, block, 8);
}
void ff_vc1_inv_trans_4x8_msa(uint8_t *dest, ptrdiff_t linesize, int16_t *block)
{
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
v4i32 in_r0, in_r1, in_r2, in_r3, in_r4, in_r5, in_r6, in_r7;
v4i32 t1, t2, t3, t4, t5, t6, t7, t8;
v4i32 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
v16i8 zero_m = { 0 };
v4i32 cnst_17 = {17, 17, 17, 17};
v4i32 cnst_22 = {22, 22, 22, 22};
v4i32 cnst_10 = {10, 10, 10, 10};
v4i32 cnst_12 = {12, 12, 12, 12};
v4i32 cnst_64 = {64, 64, 64, 64};
v4i32 cnst_16 = {16, 16, 16, 16};
v4i32 cnst_15 = {15, 15, 15, 15};
v4i32 cnst_4 = {4, 4, 4, 4};
v4i32 cnst_6 = {6, 6, 6, 6};
v4i32 cnst_9 = {9, 9, 9, 9};
v4i32 cnst_1 = {1, 1, 1, 1};
LD_SH8(block, 8, in0, in1, in2, in3, in4, in5, in6, in7);
UNPCK_R_SH_SW(in0, in_r0);
UNPCK_R_SH_SW(in1, in_r1);
UNPCK_R_SH_SW(in2, in_r2);
UNPCK_R_SH_SW(in3, in_r3);
UNPCK_R_SH_SW(in4, in_r4);
UNPCK_R_SH_SW(in5, in_r5);
UNPCK_R_SH_SW(in6, in_r6);
UNPCK_R_SH_SW(in7, in_r7);
// First loop
TRANSPOSE4x4_SW_SW(in_r0, in_r1, in_r2, in_r3, in_r0, in_r1, in_r2, in_r3);
TRANSPOSE4x4_SW_SW(in_r4, in_r5, in_r6, in_r7, in_r4, in_r5, in_r6, in_r7);
t1 = cnst_17 * (in_r0 + in_r2) + cnst_4;
t5 = cnst_17 * (in_r4 + in_r6) + cnst_4;
t2 = cnst_17 * (in_r0 - in_r2) + cnst_4;
t6 = cnst_17 * (in_r4 - in_r6) + cnst_4;
t3 = cnst_22 * in_r1 + cnst_10 * in_r3;
t7 = cnst_22 * in_r5 + cnst_10 * in_r7;
t4 = cnst_22 * in_r3 - cnst_10 * in_r1;
t8 = cnst_22 * in_r7 - cnst_10 * in_r5;
in_r0 = (t1 + t3) >> 3;
in_r4 = (t5 + t7) >> 3;
in_r1 = (t2 - t4) >> 3;
in_r5 = (t6 - t8) >> 3;
in_r2 = (t2 + t4) >> 3;
in_r6 = (t6 + t8) >> 3;
in_r3 = (t1 - t3) >> 3;
in_r7 = (t5 - t7) >> 3;
TRANSPOSE4x4_SW_SW(in_r0, in_r1, in_r2, in_r3, in_r0, in_r1, in_r2, in_r3);
TRANSPOSE4x4_SW_SW(in_r4, in_r5, in_r6, in_r7, in_r4, in_r5, in_r6, in_r7);
PCKEV_H4_SH(in_r1, in_r0, in_r3, in_r2, in_r5, in_r4, in_r7, in_r6,
in0, in1, in2, in3);
ST_D8(in0, in1, in2, in3, 0, 1, 0, 1, 0, 1, 0, 1, block, 8);
// Second loop
t1 = cnst_12 * (in_r0 + in_r4) + cnst_64;
t2 = cnst_12 * (in_r0 - in_r4) + cnst_64;
t3 = cnst_16 * in_r2 + cnst_6 * in_r6;
t4 = cnst_6 * in_r2 - cnst_16 * in_r6;
t5 = t1 + t3, t6 = t2 + t4;
t7 = t2 - t4, t8 = t1 - t3;
t1 = cnst_16 * in_r1 + cnst_15 * in_r3 + cnst_9 * in_r5 + cnst_4 * in_r7;
t2 = cnst_15 * in_r1 - cnst_4 * in_r3 - cnst_16 * in_r5 - cnst_9 * in_r7;
t3 = cnst_9 * in_r1 - cnst_16 * in_r3 + cnst_4 * in_r5 + cnst_15 * in_r7;
t4 = cnst_4 * in_r1 - cnst_9 * in_r3 + cnst_15 * in_r5 - cnst_16 * in_r7;
LD_SW8(dest, linesize, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7);
ILVR_B8_SW(zero_m, dst0, zero_m, dst1, zero_m, dst2, zero_m, dst3,
zero_m, dst4, zero_m, dst5, zero_m, dst6, zero_m, dst7,
dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7);
ILVR_H4_SW(zero_m, dst0, zero_m, dst1, zero_m, dst2, zero_m, dst3,
dst0, dst1, dst2, dst3);
ILVR_H4_SW(zero_m, dst4, zero_m, dst5, zero_m, dst6, zero_m, dst7,
dst4, dst5, dst6, dst7);
in_r0 = (t5 + t1) >> 7;
in_r1 = (t6 + t2) >> 7;
in_r2 = (t7 + t3) >> 7;
in_r3 = (t8 + t4) >> 7;
in_r4 = (t8 - t4 + cnst_1) >> 7;
in_r5 = (t7 - t3 + cnst_1) >> 7;
in_r6 = (t6 - t2 + cnst_1) >> 7;
in_r7 = (t5 - t1 + cnst_1) >> 7;
ADD4(in_r0, dst0, in_r1, dst1, in_r2, dst2, in_r3, dst3,
in_r0, in_r1, in_r2, in_r3);
ADD4(in_r4, dst4, in_r5, dst5, in_r6, dst6, in_r7, dst7,
in_r4, in_r5, in_r6, in_r7);
CLIP_SW8_0_255(in_r0, in_r1, in_r2, in_r3, in_r4, in_r5, in_r6, in_r7);
PCKEV_H4_SH(in_r1, in_r0, in_r3, in_r2, in_r5, in_r4, in_r7, in_r6,
in0, in1, in2, in3);
PCKEV_B2_SH(in1, in0, in3, in2, in0, in1);
ST_W8(in0, in1, 0, 1, 2, 3, 0, 1, 2, 3, dest, linesize);
}
void ff_vc1_inv_trans_8x4_msa(uint8_t *dest, ptrdiff_t linesize, int16_t *block)
{
v4i32 in0, in1, in2, in3, in4, in5, in6, in7;
v4i32 t1, t2, t3, t4, t5, t6, t7, t8;
v4i32 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
v16i8 zero_m = { 0 };
v4i32 cnst_17 = {17, 17, 17, 17};
v4i32 cnst_22 = {22, 22, 22, 22};
v4i32 cnst_10 = {10, 10, 10, 10};
v4i32 cnst_12 = {12, 12, 12, 12};
v4i32 cnst_64 = {64, 64, 64, 64};
v4i32 cnst_16 = {16, 16, 16, 16};
v4i32 cnst_15 = {15, 15, 15, 15};
v4i32 cnst_4 = {4, 4, 4, 4};
v4i32 cnst_6 = {6, 6, 6, 6};
v4i32 cnst_9 = {9, 9, 9, 9};
LD_SW4(block, 8, t1, t2, t3, t4);
UNPCK_SH_SW(t1, in0, in4);
UNPCK_SH_SW(t2, in1, in5);
UNPCK_SH_SW(t3, in2, in6);
UNPCK_SH_SW(t4, in3, in7);
TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, in0, in1, in2, in3);
TRANSPOSE4x4_SW_SW(in4, in5, in6, in7, in4, in5, in6, in7);
// First loop
t1 = cnst_12 * (in0 + in4) + cnst_4;
t2 = cnst_12 * (in0 - in4) + cnst_4;
t3 = cnst_16 * in2 + cnst_6 * in6;
t4 = cnst_6 * in2 - cnst_16 * in6;
t5 = t1 + t3, t6 = t2 + t4;
t7 = t2 - t4, t8 = t1 - t3;
t1 = cnst_16 * in1 + cnst_15 * in3 + cnst_9 * in5 + cnst_4 * in7;
t2 = cnst_15 * in1 - cnst_4 * in3 - cnst_16 * in5 - cnst_9 * in7;
t3 = cnst_9 * in1 - cnst_16 * in3 + cnst_4 * in5 + cnst_15 * in7;
t4 = cnst_4 * in1 - cnst_9 * in3 + cnst_15 * in5 - cnst_16 * in7;
in0 = (t5 + t1) >> 3;
in1 = (t6 + t2) >> 3;
in2 = (t7 + t3) >> 3;
in3 = (t8 + t4) >> 3;
in4 = (t8 - t4) >> 3;
in5 = (t7 - t3) >> 3;
in6 = (t6 - t2) >> 3;
in7 = (t5 - t1) >> 3;
TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, in0, in1, in2, in3);
TRANSPOSE4x4_SW_SW(in4, in5, in6, in7, in4, in5, in6, in7);
PCKEV_H4_SW(in4, in0, in5, in1, in6, in2, in7, in3, t1, t2, t3, t4);
ST_SW4(t1, t2, t3, t4, block, 8);
// Second loop
LD_SW4(dest, linesize, dst0, dst1, dst2, dst3);
ILVR_B4_SW(zero_m, dst0, zero_m, dst1, zero_m, dst2, zero_m, dst3,
dst0, dst1, dst2, dst3);
ILVL_H4_SW(zero_m, dst0, zero_m, dst1, zero_m, dst2, zero_m, dst3,
dst4, dst5, dst6, dst7);
ILVR_H4_SW(zero_m, dst0, zero_m, dst1, zero_m, dst2, zero_m, dst3,
dst0, dst1, dst2, dst3);
// Right part
t1 = cnst_17 * (in0 + in2) + cnst_64;
t2 = cnst_17 * (in0 - in2) + cnst_64;
t3 = cnst_22 * in1 + cnst_10 * in3;
t4 = cnst_22 * in3 - cnst_10 * in1;
in0 = (t1 + t3) >> 7;
in1 = (t2 - t4) >> 7;
in2 = (t2 + t4) >> 7;
in3 = (t1 - t3) >> 7;
ADD4(in0, dst0, in1, dst1, in2, dst2, in3, dst3, in0, in1, in2, in3);
CLIP_SW4_0_255(in0, in1, in2, in3);
// Left part
t5 = cnst_17 * (in4 + in6) + cnst_64;
t6 = cnst_17 * (in4 - in6) + cnst_64;
t7 = cnst_22 * in5 + cnst_10 * in7;
t8 = cnst_22 * in7 - cnst_10 * in5;
in4 = (t5 + t7) >> 7;
in5 = (t6 - t8) >> 7;
in6 = (t6 + t8) >> 7;
in7 = (t5 - t7) >> 7;
ADD4(in4, dst4, in5, dst5, in6, dst6, in7, dst7, in4, in5, in6, in7);
CLIP_SW4_0_255(in4, in5, in6, in7);
PCKEV_H4_SW(in4, in0, in5, in1, in6, in2, in7, in3, in0, in1, in2, in3);
PCKEV_B2_SW(in1, in0, in3, in2, in0, in1);
ST_D4(in0, in1, 0, 1, 0, 1, dest, linesize);
}
static void put_vc1_mspel_mc_h_v_msa(uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int hmode, int vmode,
int rnd)
{
v8i16 in_r0, in_r1, in_r2, in_r3, in_l0, in_l1, in_l2, in_l3;
v8i16 t0, t1, t2, t3, t4, t5, t6, t7;
v8i16 t8, t9, t10, t11, t12, t13, t14, t15;
v8i16 cnst_para0, cnst_para1, cnst_para2, cnst_para3, cnst_r;
static const int para_value[][4] = {{4, 53, 18, 3},
{1, 9, 9, 1},
{3, 18, 53, 4}};
static const int shift_value[] = {0, 5, 1, 5};
int shift = (shift_value[hmode] + shift_value[vmode]) >> 1;
int r = (1 << (shift - 1)) + rnd - 1;
cnst_r = __msa_fill_h(r);
src -= 1, src -= stride;
cnst_para0 = __msa_fill_h(para_value[vmode - 1][0]);
cnst_para1 = __msa_fill_h(para_value[vmode - 1][1]);
cnst_para2 = __msa_fill_h(para_value[vmode - 1][2]);
cnst_para3 = __msa_fill_h(para_value[vmode - 1][3]);
LD_SH4(src, stride, in_l0, in_l1, in_l2, in_l3);
UNPCK_UB_SH(in_l0, in_r0, in_l0);
UNPCK_UB_SH(in_l1, in_r1, in_l1);
UNPCK_UB_SH(in_l2, in_r2, in_l2);
UNPCK_UB_SH(in_l3, in_r3, in_l3);
// row 0
t0 = cnst_para1 * in_r1 + cnst_para2 * in_r2
- cnst_para0 * in_r0 - cnst_para3 * in_r3;
t8 = cnst_para1 * in_l1 + cnst_para2 * in_l2
- cnst_para0 * in_l0 - cnst_para3 * in_l3;
in_l0 = LD_SH(src + 4 * stride);
UNPCK_UB_SH(in_l0, in_r0, in_l0);
// row 1
t1 = cnst_para1 * in_r2 + cnst_para2 * in_r3
- cnst_para0 * in_r1 - cnst_para3 * in_r0;
t9 = cnst_para1 * in_l2 + cnst_para2 * in_l3
- cnst_para0 * in_l1 - cnst_para3 * in_l0;
in_l1 = LD_SH(src + 5 * stride);
UNPCK_UB_SH(in_l1, in_r1, in_l1);
// row 2
t2 = cnst_para1 * in_r3 + cnst_para2 * in_r0
- cnst_para0 * in_r2 - cnst_para3 * in_r1;
t10 = cnst_para1 * in_l3 + cnst_para2 * in_l0
- cnst_para0 * in_l2 - cnst_para3 * in_l1;
in_l2 = LD_SH(src + 6 * stride);
UNPCK_UB_SH(in_l2, in_r2, in_l2);
// row 3
t3 = cnst_para1 * in_r0 + cnst_para2 * in_r1
- cnst_para0 * in_r3 - cnst_para3 * in_r2;
t11 = cnst_para1 * in_l0 + cnst_para2 * in_l1
- cnst_para0 * in_l3 - cnst_para3 * in_l2;
in_l3 = LD_SH(src + 7 * stride);
UNPCK_UB_SH(in_l3, in_r3, in_l3);
// row 4
t4 = cnst_para1 * in_r1 + cnst_para2 * in_r2
- cnst_para0 * in_r0 - cnst_para3 * in_r3;
t12 = cnst_para1 * in_l1 + cnst_para2 * in_l2
- cnst_para0 * in_l0 - cnst_para3 * in_l3;
in_l0 = LD_SH(src + 8 * stride);
UNPCK_UB_SH(in_l0, in_r0, in_l0);
// row 5
t5 = cnst_para1 * in_r2 + cnst_para2 * in_r3
- cnst_para0 * in_r1 - cnst_para3 * in_r0;
t13 = cnst_para1 * in_l2 + cnst_para2 * in_l3
- cnst_para0 * in_l1 - cnst_para3 * in_l0;
in_l1 = LD_SH(src + 9 * stride);
UNPCK_UB_SH(in_l1, in_r1, in_l1);
// row 6
t6 = cnst_para1 * in_r3 + cnst_para2 * in_r0
- cnst_para0 * in_r2 - cnst_para3 * in_r1;
t14 = cnst_para1 * in_l3 + cnst_para2 * in_l0
- cnst_para0 * in_l2 - cnst_para3 * in_l1;
in_l2 = LD_SH(src + 10 * stride);
UNPCK_UB_SH(in_l2, in_r2, in_l2);
// row 7
t7 = cnst_para1 * in_r0 + cnst_para2 * in_r1
- cnst_para0 * in_r3 - cnst_para3 * in_r2;
t15 = cnst_para1 * in_l0 + cnst_para2 * in_l1
- cnst_para0 * in_l3 - cnst_para3 * in_l2;
ADD4(t0, cnst_r, t1, cnst_r, t2, cnst_r, t3, cnst_r, t0, t1, t2, t3);
ADD4(t4, cnst_r, t5, cnst_r, t6, cnst_r, t7, cnst_r, t4, t5, t6, t7);
ADD4(t8, cnst_r, t9, cnst_r, t10, cnst_r, t11, cnst_r,
t8, t9, t10, t11);
ADD4(t12, cnst_r, t13, cnst_r, t14, cnst_r, t15, cnst_r,
t12, t13, t14, t15);
t0 >>= shift, t1 >>= shift, t2 >>= shift, t3 >>= shift;
t4 >>= shift, t5 >>= shift, t6 >>= shift, t7 >>= shift;
t8 >>= shift, t9 >>= shift, t10 >>= shift, t11 >>= shift;
t12 >>= shift, t13 >>= shift, t14 >>= shift, t15 >>= shift;
TRANSPOSE8x8_SH_SH(t0, t1, t2, t3, t4, t5, t6, t7,
t0, t1, t2, t3, t4, t5, t6, t7);
TRANSPOSE8x8_SH_SH(t8, t9, t10, t11, t12, t13, t14, t15,
t8, t9, t10, t11, t12, t13, t14, t15);
cnst_para0 = __msa_fill_h(para_value[hmode - 1][0]);
cnst_para1 = __msa_fill_h(para_value[hmode - 1][1]);
cnst_para2 = __msa_fill_h(para_value[hmode - 1][2]);
cnst_para3 = __msa_fill_h(para_value[hmode - 1][3]);
r = 64 - rnd;
cnst_r = __msa_fill_h(r);
// col 0 ~ 7
t0 = cnst_para1 * t1 + cnst_para2 * t2 - cnst_para0 * t0 - cnst_para3 * t3;
t1 = cnst_para1 * t2 + cnst_para2 * t3 - cnst_para0 * t1 - cnst_para3 * t4;
t2 = cnst_para1 * t3 + cnst_para2 * t4 - cnst_para0 * t2 - cnst_para3 * t5;
t3 = cnst_para1 * t4 + cnst_para2 * t5 - cnst_para0 * t3 - cnst_para3 * t6;
t4 = cnst_para1 * t5 + cnst_para2 * t6 - cnst_para0 * t4 - cnst_para3 * t7;
t5 = cnst_para1 * t6 + cnst_para2 * t7 - cnst_para0 * t5 - cnst_para3 * t8;
t6 = cnst_para1 * t7 + cnst_para2 * t8 - cnst_para0 * t6 - cnst_para3 * t9;
t7 = cnst_para1 * t8 + cnst_para2 * t9 - cnst_para0 * t7 - cnst_para3 * t10;
ADD4(t0, cnst_r, t1, cnst_r, t2, cnst_r, t3, cnst_r, t0, t1, t2, t3);
ADD4(t4, cnst_r, t5, cnst_r, t6, cnst_r, t7, cnst_r, t4, t5, t6, t7);
t0 >>= 7, t1 >>= 7, t2 >>= 7, t3 >>= 7;
t4 >>= 7, t5 >>= 7, t6 >>= 7, t7 >>= 7;
TRANSPOSE8x8_SH_SH(t0, t1, t2, t3, t4, t5, t6, t7,
t0, t1, t2, t3, t4, t5, t6, t7);
CLIP_SH8_0_255(t0, t1, t2, t3, t4, t5, t6, t7);
PCKEV_B4_SH(t1, t0, t3, t2, t5, t4, t7, t6, t0, t1, t2, t3);
ST_D8(t0, t1, t2, t3, 0, 1, 0, 1, 0, 1, 0, 1, dst, stride);
}
#define PUT_VC1_MSPEL_MC_MSA(hmode, vmode) \
void ff_put_vc1_mspel_mc ## hmode ## vmode ## _msa(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t stride, int rnd) \
{ \
put_vc1_mspel_mc_h_v_msa(dst, src, stride, hmode, vmode, rnd); \
} \
void ff_put_vc1_mspel_mc ## hmode ## vmode ## _16_msa(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t stride, int rnd) \
{ \
put_vc1_mspel_mc_h_v_msa(dst, src, stride, hmode, vmode, rnd); \
put_vc1_mspel_mc_h_v_msa(dst + 8, src + 8, stride, hmode, vmode, rnd); \
dst += 8 * stride, src += 8 * stride; \
put_vc1_mspel_mc_h_v_msa(dst, src, stride, hmode, vmode, rnd); \
put_vc1_mspel_mc_h_v_msa(dst + 8, src + 8, stride, hmode, vmode, rnd); \
}
PUT_VC1_MSPEL_MC_MSA(1, 1);
PUT_VC1_MSPEL_MC_MSA(1, 2);
PUT_VC1_MSPEL_MC_MSA(1, 3);
PUT_VC1_MSPEL_MC_MSA(2, 1);
PUT_VC1_MSPEL_MC_MSA(2, 2);
PUT_VC1_MSPEL_MC_MSA(2, 3);
PUT_VC1_MSPEL_MC_MSA(3, 1);
PUT_VC1_MSPEL_MC_MSA(3, 2);
PUT_VC1_MSPEL_MC_MSA(3, 3);

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2017 Kaustubh Raste (kaustubh.raste@imgtec.com)
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/mips/asmdefs.h"
#include "libavcodec/videodsp.h"
#if HAVE_MSA
static void prefetch_mips(uint8_t *mem, ptrdiff_t stride, int h)
{
register const uint8_t *p = mem;
__asm__ volatile (
"1: \n\t"
"pref 4, 0(%[p]) \n\t"
"pref 4, 32(%[p]) \n\t"
PTR_ADDIU" %[h], %[h], -1 \n\t"
PTR_ADDU " %[p], %[p], %[stride] \n\t"
"bnez %[h], 1b \n\t"
: [p] "+r" (p), [h] "+r" (h)
: [stride] "r" (stride)
);
}
#endif // #if HAVE_MSA
av_cold void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc)
{
#if HAVE_MSA
ctx->prefetch = prefetch_mips;
#endif // #if HAVE_MSA
}

View File

@@ -0,0 +1,769 @@
/*
* Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vp3dsp_mips.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mips/mmiutils.h"
#include "libavutil/common.h"
#include "libavcodec/rnd_avg.h"
#define LOAD_CONST(dst, value) \
"li %[tmp1], "#value" \n\t" \
"dmtc1 %[tmp1], "#dst" \n\t" \
"pshufh "#dst", "#dst", %[ftmp10] \n\t"
static void idct_row_mmi(int16_t *input)
{
double ftmp[23];
uint64_t tmp[2];
__asm__ volatile (
"xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t"
LOAD_CONST(%[csth_1], 1)
"li %[tmp0], 0x02 \n\t"
"1: \n\t"
/* Load input */
"ldc1 %[ftmp0], 0x00(%[input]) \n\t"
"ldc1 %[ftmp1], 0x10(%[input]) \n\t"
"ldc1 %[ftmp2], 0x20(%[input]) \n\t"
"ldc1 %[ftmp3], 0x30(%[input]) \n\t"
"ldc1 %[ftmp4], 0x40(%[input]) \n\t"
"ldc1 %[ftmp5], 0x50(%[input]) \n\t"
"ldc1 %[ftmp6], 0x60(%[input]) \n\t"
"ldc1 %[ftmp7], 0x70(%[input]) \n\t"
LOAD_CONST(%[ftmp8], 64277)
LOAD_CONST(%[ftmp9], 12785)
"pmulhh %[A], %[ftmp9], %[ftmp7] \n\t"
"pcmpgth %[C], %[ftmp10], %[ftmp1] \n\t"
"or %[mask], %[C], %[csth_1] \n\t"
"pmullh %[B], %[ftmp1], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"paddh %[A], %[A], %[C] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp7] \n\t"
"or %[mask], %[D], %[csth_1] \n\t"
"pmullh %[ftmp7], %[ftmp7], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[ftmp7] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhh %[C], %[ftmp9], %[ftmp1] \n\t"
"psubh %[B], %[C], %[B] \n\t"
"psubh %[B], %[B], %[D] \n\t"
LOAD_CONST(%[ftmp8], 54491)
LOAD_CONST(%[ftmp9], 36410)
"pcmpgth %[Ad], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ad], %[csth_1] \n\t"
"pmullh %[ftmp1], %[ftmp5], %[mask] \n\t"
"pmulhuh %[C], %[ftmp9], %[ftmp1] \n\t"
"pmullh %[C], %[C], %[mask] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[csth_1] \n\t"
"pmullh %[D], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[D] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"paddh %[C], %[C], %[Ad] \n\t"
"paddh %[C], %[C], %[Bd] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[csth_1] \n\t"
"pmullh %[ftmp1], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp9], %[ftmp1] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ed], %[csth_1] \n\t"
"pmullh %[Ad], %[ftmp5], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"psubh %[D], %[Ad], %[D] \n\t"
"paddh %[D], %[D], %[Ed] \n\t"
"psubh %[D], %[D], %[Bd] \n\t"
LOAD_CONST(%[ftmp8], 46341)
"psubh %[Ad], %[A], %[C] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[Ad] \n\t"
"or %[mask], %[Bd], %[csth_1] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"paddh %[Ad], %[Ad], %[Bd] \n\t"
"psubh %[Bd], %[B], %[D] \n\t"
"pcmpgth %[Cd], %[ftmp10], %[Bd] \n\t"
"or %[mask], %[Cd], %[csth_1] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"pmulhuh %[Bd], %[ftmp8], %[Bd] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"paddh %[Bd], %[Bd], %[Cd] \n\t"
"paddh %[Cd], %[A], %[C] \n\t"
"paddh %[Dd], %[B], %[D] \n\t"
"paddh %[A], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[B], %[ftmp10], %[A] \n\t"
"or %[mask], %[B], %[csth_1] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"pmulhuh %[A], %[ftmp8], %[A] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"psubh %[B], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[C], %[ftmp10], %[B] \n\t"
"or %[mask], %[C], %[csth_1] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[B], %[B], %[C] \n\t"
LOAD_CONST(%[ftmp8], 60547)
LOAD_CONST(%[ftmp9], 25080)
"pmulhh %[C], %[ftmp9], %[ftmp6] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp2] \n\t"
"or %[mask], %[D], %[csth_1] \n\t"
"pmullh %[Ed], %[ftmp2], %[mask] \n\t"
"pmulhuh %[Ed], %[ftmp8], %[Ed] \n\t"
"pmullh %[Ed], %[Ed], %[mask] \n\t"
"paddh %[C], %[C], %[Ed] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp6] \n\t"
"or %[mask], %[Ed], %[csth_1] \n\t"
"pmullh %[ftmp6], %[ftmp6], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[ftmp6] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pmulhh %[Gd], %[ftmp9], %[ftmp2] \n\t"
"psubh %[D], %[Gd], %[D] \n\t"
"psubh %[D], %[D], %[Ed] \n\t"
"psubh %[Ed], %[A], %[C] \n\t"
"paddh %[Gd], %[A], %[C] \n\t"
"paddh %[A], %[B], %[Ad] \n\t"
"psubh %[C], %[B], %[Ad] \n\t"
"psubh %[B], %[Bd], %[D] \n\t"
"paddh %[D], %[Bd], %[D] \n\t"
/* Final sequence of operations over-write original inputs */
"paddh %[ftmp0], %[Gd], %[Cd] \n\t"
"paddh %[ftmp1], %[A], %[D] \n\t"
"psubh %[ftmp2], %[A], %[D] \n\t"
"paddh %[ftmp3], %[Ed], %[Dd] \n\t"
"psubh %[ftmp4], %[Ed], %[Dd] \n\t"
"paddh %[ftmp5], %[C], %[B] \n\t"
"psubh %[ftmp6], %[C], %[B] \n\t"
"psubh %[ftmp7], %[Gd], %[Cd] \n\t"
"sdc1 %[ftmp0], 0x00(%[input]) \n\t"
"sdc1 %[ftmp1], 0x10(%[input]) \n\t"
"sdc1 %[ftmp2], 0x20(%[input]) \n\t"
"sdc1 %[ftmp3], 0x30(%[input]) \n\t"
"sdc1 %[ftmp4], 0x40(%[input]) \n\t"
"sdc1 %[ftmp5], 0x50(%[input]) \n\t"
"sdc1 %[ftmp6], 0x60(%[input]) \n\t"
"sdc1 %[ftmp7], 0x70(%[input]) \n\t"
PTR_ADDU "%[tmp0], %[tmp0], -0x01 \n\t"
PTR_ADDIU "%[input], %[input], 0x08 \n\t"
"bnez %[tmp0], 1b \n\t"
: [input]"+&r"(input), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
[ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
[ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
[A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
[D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
[Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
[Gd]"=&f"(ftmp[21]), [csth_1]"=&f"(ftmp[22])
:
: "memory"
);
}
static void idct_column_true_mmi(uint8_t *dst, int stride, int16_t *input)
{
uint8_t temp_value[8];
double ftmp[23];
uint64_t tmp[2];
for (int i = 0; i < 8; ++i)
temp_value[i] = av_clip_uint8(128 + ((46341 * input[i << 3] + (8 << 16)) >> 20));
__asm__ volatile (
"xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t"
"li %[tmp0], 0x02 \n\t"
"1: \n\t"
"ldc1 %[ftmp0], 0x00(%[input]) \n\t"
"ldc1 %[ftmp4], 0x08(%[input]) \n\t"
"ldc1 %[ftmp1], 0x10(%[input]) \n\t"
"ldc1 %[ftmp5], 0x18(%[input]) \n\t"
"ldc1 %[ftmp2], 0x20(%[input]) \n\t"
"ldc1 %[ftmp6], 0x28(%[input]) \n\t"
"ldc1 %[ftmp3], 0x30(%[input]) \n\t"
"ldc1 %[ftmp7], 0x38(%[input]) \n\t"
TRANSPOSE_4H(%[ftmp0], %[ftmp1], %[ftmp2], %[ftmp3],
%[A], %[B], %[C], %[D])
TRANSPOSE_4H(%[ftmp4], %[ftmp5], %[ftmp6], %[ftmp7],
%[A], %[B], %[C], %[D])
LOAD_CONST(%[ftmp8], 64277)
LOAD_CONST(%[ftmp9], 12785)
LOAD_CONST(%[Gd], 1)
"pmulhh %[A], %[ftmp9], %[ftmp7] \n\t"
"pcmpgth %[C], %[ftmp10], %[ftmp1] \n\t"
"or %[mask], %[C], %[Gd] \n\t"
"pmullh %[B], %[ftmp1], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"paddh %[A], %[A], %[C] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp7] \n\t"
"or %[mask], %[D], %[Gd] \n\t"
"pmullh %[Ad], %[ftmp7], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[Ad] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhh %[C], %[ftmp9], %[ftmp1] \n\t"
"psubh %[B], %[C], %[B] \n\t"
"psubh %[B], %[B], %[D] \n\t"
LOAD_CONST(%[ftmp8], 54491)
LOAD_CONST(%[ftmp9], 36410)
"pcmpgth %[Ad], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ad], %[Gd] \n\t"
"pmullh %[Cd], %[ftmp5], %[mask] \n\t"
"pmulhuh %[C], %[ftmp9], %[Cd] \n\t"
"pmullh %[C], %[C], %[mask] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[D], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[D] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"paddh %[C], %[C], %[Ad] \n\t"
"paddh %[C], %[C], %[Bd] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[Cd], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp9], %[Cd] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ed], %[Gd] \n\t"
"pmullh %[Ad], %[ftmp5], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"psubh %[D], %[Ad], %[D] \n\t"
"paddh %[D], %[D], %[Ed] \n\t"
"psubh %[D], %[D], %[Bd] \n\t"
LOAD_CONST(%[ftmp8], 46341)
"psubh %[Ad], %[A], %[C] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[Ad] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"paddh %[Ad], %[Ad], %[Bd] \n\t"
"psubh %[Bd], %[B], %[D] \n\t"
"pcmpgth %[Cd], %[ftmp10], %[Bd] \n\t"
"or %[mask], %[Cd], %[Gd] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"pmulhuh %[Bd], %[ftmp8], %[Bd] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"paddh %[Bd], %[Bd], %[Cd] \n\t"
"paddh %[Cd], %[A], %[C] \n\t"
"paddh %[Dd], %[B], %[D] \n\t"
LOAD_CONST(%[Ed], 2056)
"paddh %[A], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[B], %[ftmp10], %[A] \n\t"
"or %[mask], %[B], %[Gd] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"pmulhuh %[A], %[ftmp8], %[A] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"paddh %[A], %[A], %[Ed] \n\t"
"psubh %[B], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[C], %[ftmp10], %[B] \n\t"
"or %[mask], %[C], %[Gd] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[B], %[B], %[C] \n\t"
"paddh %[B], %[B], %[Ed] \n\t"
LOAD_CONST(%[ftmp8], 60547)
LOAD_CONST(%[ftmp9], 25080)
"pmulhh %[C], %[ftmp9], %[ftmp6] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp2] \n\t"
"or %[mask], %[D], %[Gd] \n\t"
"pmullh %[Ed], %[ftmp2], %[mask] \n\t"
"pmulhuh %[Ed], %[ftmp8], %[Ed] \n\t"
"pmullh %[Ed], %[Ed], %[mask] \n\t"
"paddh %[C], %[C], %[Ed] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp6] \n\t"
"or %[mask], %[Ed], %[Gd] \n\t"
"pmullh %[D], %[ftmp6], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[D] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pmulhh %[Gd], %[ftmp9], %[ftmp2] \n\t"
"psubh %[D], %[Gd], %[D] \n\t"
"psubh %[D], %[D], %[Ed] \n\t"
"psubh %[Ed], %[A], %[C] \n\t"
"paddh %[Gd], %[A], %[C] \n\t"
"paddh %[A], %[B], %[Ad] \n\t"
"psubh %[C], %[B], %[Ad] \n\t"
"psubh %[B], %[Bd], %[D] \n\t"
"paddh %[D], %[Bd], %[D] \n\t"
"or %[mask], %[ftmp1], %[ftmp2] \n\t"
"or %[mask], %[mask], %[ftmp3] \n\t"
"or %[mask], %[mask], %[ftmp4] \n\t"
"or %[mask], %[mask], %[ftmp5] \n\t"
"or %[mask], %[mask], %[ftmp6] \n\t"
"or %[mask], %[mask], %[ftmp7] \n\t"
"pcmpeqh %[mask], %[mask], %[ftmp10] \n\t"
"packushb %[mask], %[mask], %[ftmp10] \n\t"
"li %[tmp1], 0x04 \n\t"
"dmtc1 %[tmp1], %[ftmp8] \n\t"
"paddh %[ftmp0], %[Gd], %[Cd] \n\t"
"psrah %[ftmp0], %[ftmp0], %[ftmp8] \n\t"
"paddh %[ftmp1], %[A], %[D] \n\t"
"psrah %[ftmp1], %[ftmp1], %[ftmp8] \n\t"
"psubh %[ftmp2], %[A], %[D] \n\t"
"psrah %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"paddh %[ftmp3], %[Ed], %[Dd] \n\t"
"psrah %[ftmp3], %[ftmp3], %[ftmp8] \n\t"
"psubh %[ftmp4], %[Ed], %[Dd] \n\t"
"psrah %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
"paddh %[ftmp5], %[C], %[B] \n\t"
"psrah %[ftmp5], %[ftmp5], %[ftmp8] \n\t"
"psubh %[ftmp6], %[C], %[B] \n\t"
"psrah %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"psubh %[ftmp7], %[Gd], %[Cd] \n\t"
"psrah %[ftmp7], %[ftmp7], %[ftmp8] \n\t"
"pmaxsh %[ftmp0], %[ftmp0], %[ftmp10] \n\t"
"packushb %[ftmp0], %[ftmp0], %[ftmp10] \n\t"
"pmaxsh %[ftmp1], %[ftmp1], %[ftmp10] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp10] \n\t"
"pmaxsh %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
"packushb %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
"pmaxsh %[ftmp3], %[ftmp3], %[ftmp10] \n\t"
"packushb %[ftmp3], %[ftmp3], %[ftmp10] \n\t"
"pmaxsh %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
"packushb %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
"pmaxsh %[ftmp5], %[ftmp5], %[ftmp10] \n\t"
"packushb %[ftmp5], %[ftmp5], %[ftmp10] \n\t"
"pmaxsh %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
"packushb %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
"pmaxsh %[ftmp7], %[ftmp7], %[ftmp10] \n\t"
"packushb %[ftmp7], %[ftmp7], %[ftmp10] \n\t"
"lwc1 %[Ed], 0x00(%[temp_value]) \n\t"
"and %[Ed], %[Ed], %[mask] \n\t"
"paddb %[ftmp0], %[ftmp0], %[Ed] \n\t"
"paddb %[ftmp1], %[ftmp1], %[Ed] \n\t"
"paddb %[ftmp2], %[ftmp2], %[Ed] \n\t"
"paddb %[ftmp3], %[ftmp3], %[Ed] \n\t"
"paddb %[ftmp4], %[ftmp4], %[Ed] \n\t"
"paddb %[ftmp5], %[ftmp5], %[Ed] \n\t"
"paddb %[ftmp6], %[ftmp6], %[Ed] \n\t"
"paddb %[ftmp7], %[ftmp7], %[Ed] \n\t"
"swc1 %[ftmp0], 0x00(%[dst]) \n\t"
PTR_ADDU "%[tmp1], %[dst], %[stride] \n\t"
"swc1 %[ftmp1], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp2], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp3], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp4], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp5], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp6], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp7], 0x00(%[tmp1]) \n\t"
PTR_ADDIU "%[dst], %[dst], 0x04 \n\t"
PTR_ADDIU "%[input], %[input], 0x40 \n\t"
PTR_ADDIU "%[temp_value], %[temp_value], 0x04 \n\t"
PTR_ADDIU "%[tmp0], %[tmp0], -0x01 \n\t"
"bnez %[tmp0], 1b \n\t"
: [dst]"+&r"(dst), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
[ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
[ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
[A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
[D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
[Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
[Gd]"=&f"(ftmp[21]), [input]"+&r"(input)
: [stride]"r"(stride), [temp_value]"r"(temp_value)
: "memory"
);
}
static void idct_column_false_mmi(uint8_t *dst, int stride, int16_t *input)
{
int16_t temp_value[8];
double ftmp[23];
uint64_t tmp[2];
for (int i = 0; i < 8; ++i)
temp_value[i] = (46341 * input[i << 3] + (8 << 16)) >> 20;
__asm__ volatile (
"xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t"
"li %[tmp0], 0x02 \n\t"
"1: \n\t"
"ldc1 %[ftmp0], 0x00(%[input]) \n\t"
"ldc1 %[ftmp4], 0x08(%[input]) \n\t"
"ldc1 %[ftmp1], 0x10(%[input]) \n\t"
"ldc1 %[ftmp5], 0x18(%[input]) \n\t"
"ldc1 %[ftmp2], 0x20(%[input]) \n\t"
"ldc1 %[ftmp6], 0x28(%[input]) \n\t"
"ldc1 %[ftmp3], 0x30(%[input]) \n\t"
"ldc1 %[ftmp7], 0x38(%[input]) \n\t"
TRANSPOSE_4H(%[ftmp0], %[ftmp1], %[ftmp2], %[ftmp3],
%[A], %[B], %[C], %[D])
TRANSPOSE_4H(%[ftmp4], %[ftmp5], %[ftmp6], %[ftmp7],
%[A], %[B], %[C], %[D])
LOAD_CONST(%[ftmp8], 64277)
LOAD_CONST(%[ftmp9], 12785)
LOAD_CONST(%[Gd], 1)
"pmulhh %[A], %[ftmp9], %[ftmp7] \n\t"
"pcmpgth %[C], %[ftmp10], %[ftmp1] \n\t"
"or %[mask], %[C], %[Gd] \n\t"
"pmullh %[B], %[ftmp1], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"paddh %[A], %[A], %[C] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp7] \n\t"
"or %[mask], %[D], %[Gd] \n\t"
"pmullh %[Ad], %[ftmp7], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[Ad] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhh %[C], %[ftmp9], %[ftmp1] \n\t"
"psubh %[B], %[C], %[B] \n\t"
"psubh %[B], %[B], %[D] \n\t"
LOAD_CONST(%[ftmp8], 54491)
LOAD_CONST(%[ftmp9], 36410)
"pcmpgth %[Ad], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ad], %[Gd] \n\t"
"pmullh %[Cd], %[ftmp5], %[mask] \n\t"
"pmulhuh %[C], %[ftmp9], %[Cd] \n\t"
"pmullh %[C], %[C], %[mask] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[D], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[D] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"paddh %[C], %[C], %[Ad] \n\t"
"paddh %[C], %[C], %[Bd] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[ftmp3] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[Cd], %[ftmp3], %[mask] \n\t"
"pmulhuh %[D], %[ftmp9], %[Cd] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp5] \n\t"
"or %[mask], %[Ed], %[Gd] \n\t"
"pmullh %[Ad], %[ftmp5], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"psubh %[D], %[Ad], %[D] \n\t"
"paddh %[D], %[D], %[Ed] \n\t"
"psubh %[D], %[D], %[Bd] \n\t"
LOAD_CONST(%[ftmp8], 46341)
"psubh %[Ad], %[A], %[C] \n\t"
"pcmpgth %[Bd], %[ftmp10], %[Ad] \n\t"
"or %[mask], %[Bd], %[Gd] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"pmulhuh %[Ad], %[ftmp8], %[Ad] \n\t"
"pmullh %[Ad], %[Ad], %[mask] \n\t"
"paddh %[Ad], %[Ad], %[Bd] \n\t"
"psubh %[Bd], %[B], %[D] \n\t"
"pcmpgth %[Cd], %[ftmp10], %[Bd] \n\t"
"or %[mask], %[Cd], %[Gd] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"pmulhuh %[Bd], %[ftmp8], %[Bd] \n\t"
"pmullh %[Bd], %[Bd], %[mask] \n\t"
"paddh %[Bd], %[Bd], %[Cd] \n\t"
"paddh %[Cd], %[A], %[C] \n\t"
"paddh %[Dd], %[B], %[D] \n\t"
LOAD_CONST(%[Ed], 8)
"paddh %[A], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[B], %[ftmp10], %[A] \n\t"
"or %[mask], %[B], %[Gd] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"pmulhuh %[A], %[ftmp8], %[A] \n\t"
"pmullh %[A], %[A], %[mask] \n\t"
"paddh %[A], %[A], %[B] \n\t"
"paddh %[A], %[A], %[Ed] \n\t"
"psubh %[B], %[ftmp0], %[ftmp4] \n\t"
"pcmpgth %[C], %[ftmp10], %[B] \n\t"
"or %[mask], %[C], %[Gd] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"pmulhuh %[B], %[ftmp8], %[B] \n\t"
"pmullh %[B], %[B], %[mask] \n\t"
"paddh %[B], %[B], %[C] \n\t"
"paddh %[B], %[B], %[Ed] \n\t"
LOAD_CONST(%[ftmp8], 60547)
LOAD_CONST(%[ftmp9], 25080)
"pmulhh %[C], %[ftmp9], %[ftmp6] \n\t"
"pcmpgth %[D], %[ftmp10], %[ftmp2] \n\t"
"or %[mask], %[D], %[Gd] \n\t"
"pmullh %[Ed], %[ftmp2], %[mask] \n\t"
"pmulhuh %[Ed], %[ftmp8], %[Ed] \n\t"
"pmullh %[Ed], %[Ed], %[mask] \n\t"
"paddh %[C], %[C], %[Ed] \n\t"
"paddh %[C], %[C], %[D] \n\t"
"pcmpgth %[Ed], %[ftmp10], %[ftmp6] \n\t"
"or %[mask], %[Ed], %[Gd] \n\t"
"pmullh %[D], %[ftmp6], %[mask] \n\t"
"pmulhuh %[D], %[ftmp8], %[D] \n\t"
"pmullh %[D], %[D], %[mask] \n\t"
"pmulhh %[Gd], %[ftmp9], %[ftmp2] \n\t"
"psubh %[D], %[Gd], %[D] \n\t"
"psubh %[D], %[D], %[Ed] \n\t"
"psubh %[Ed], %[A], %[C] \n\t"
"paddh %[Gd], %[A], %[C] \n\t"
"paddh %[A], %[B], %[Ad] \n\t"
"psubh %[C], %[B], %[Ad] \n\t"
"psubh %[B], %[Bd], %[D] \n\t"
"paddh %[D], %[Bd], %[D] \n\t"
"or %[mask], %[ftmp1], %[ftmp2] \n\t"
"or %[mask], %[mask], %[ftmp3] \n\t"
"or %[mask], %[mask], %[ftmp4] \n\t"
"or %[mask], %[mask], %[ftmp5] \n\t"
"or %[mask], %[mask], %[ftmp6] \n\t"
"or %[mask], %[mask], %[ftmp7] \n\t"
"pcmpeqh %[mask], %[mask], %[ftmp10] \n\t"
"li %[tmp1], 0x04 \n\t"
"dmtc1 %[tmp1], %[ftmp8] \n\t"
"paddh %[ftmp0], %[Gd], %[Cd] \n\t"
"psrah %[ftmp0], %[ftmp0], %[ftmp8] \n\t"
"paddh %[ftmp1], %[A], %[D] \n\t"
"psrah %[ftmp1], %[ftmp1], %[ftmp8] \n\t"
"psubh %[ftmp2], %[A], %[D] \n\t"
"psrah %[ftmp2], %[ftmp2], %[ftmp8] \n\t"
"paddh %[ftmp3], %[Ed], %[Dd] \n\t"
"psrah %[ftmp3], %[ftmp3], %[ftmp8] \n\t"
"psubh %[ftmp4], %[Ed], %[Dd] \n\t"
"psrah %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
"paddh %[ftmp5], %[C], %[B] \n\t"
"psrah %[ftmp5], %[ftmp5], %[ftmp8] \n\t"
"psubh %[ftmp6], %[C], %[B] \n\t"
"psrah %[ftmp6], %[ftmp6], %[ftmp8] \n\t"
"psubh %[ftmp7], %[Gd], %[Cd] \n\t"
"psrah %[ftmp7], %[ftmp7], %[ftmp8] \n\t"
/* Load from dst */
"lwc1 %[A], 0x00(%[dst]) \n\t"
PTR_ADDU "%[tmp1], %[dst], %[stride] \n\t"
"lwc1 %[B], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[C], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[D], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[Ad], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[Bd], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[Cd], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"lwc1 %[Dd], 0x00(%[tmp1]) \n\t"
"punpcklbh %[A], %[A], %[ftmp10] \n\t"
"punpcklbh %[B], %[B], %[ftmp10] \n\t"
"punpcklbh %[C], %[C], %[ftmp10] \n\t"
"punpcklbh %[D], %[D], %[ftmp10] \n\t"
"punpcklbh %[Ad], %[Ad], %[ftmp10] \n\t"
"punpcklbh %[Bd], %[Bd], %[ftmp10] \n\t"
"punpcklbh %[Cd], %[Cd], %[ftmp10] \n\t"
"punpcklbh %[Dd], %[Dd], %[ftmp10] \n\t"
"ldc1 %[Ed], 0x00(%[temp_value]) \n\t"
"and %[Ed], %[Ed], %[mask] \n\t"
"nor %[mask], %[mask], %[mask] \n\t"
"and %[ftmp0], %[ftmp0], %[mask] \n\t"
"and %[ftmp1], %[ftmp1], %[mask] \n\t"
"and %[ftmp2], %[ftmp2], %[mask] \n\t"
"and %[ftmp3], %[ftmp3], %[mask] \n\t"
"and %[ftmp4], %[ftmp4], %[mask] \n\t"
"and %[ftmp5], %[ftmp5], %[mask] \n\t"
"and %[ftmp6], %[ftmp6], %[mask] \n\t"
"and %[ftmp7], %[ftmp7], %[mask] \n\t"
"paddh %[ftmp0], %[ftmp0], %[A] \n\t"
"paddh %[ftmp1], %[ftmp1], %[B] \n\t"
"paddh %[ftmp2], %[ftmp2], %[C] \n\t"
"paddh %[ftmp3], %[ftmp3], %[D] \n\t"
"paddh %[ftmp4], %[ftmp4], %[Ad] \n\t"
"paddh %[ftmp5], %[ftmp5], %[Bd] \n\t"
"paddh %[ftmp6], %[ftmp6], %[Cd] \n\t"
"paddh %[ftmp7], %[ftmp7], %[Dd] \n\t"
"paddh %[ftmp0], %[ftmp0], %[Ed] \n\t"
"paddh %[ftmp1], %[ftmp1], %[Ed] \n\t"
"paddh %[ftmp2], %[ftmp2], %[Ed] \n\t"
"paddh %[ftmp3], %[ftmp3], %[Ed] \n\t"
"paddh %[ftmp4], %[ftmp4], %[Ed] \n\t"
"paddh %[ftmp5], %[ftmp5], %[Ed] \n\t"
"paddh %[ftmp6], %[ftmp6], %[Ed] \n\t"
"paddh %[ftmp7], %[ftmp7], %[Ed] \n\t"
"pmaxsh %[ftmp0], %[ftmp0], %[ftmp10] \n\t"
"packushb %[ftmp0], %[ftmp0], %[ftmp10] \n\t"
"pmaxsh %[ftmp1], %[ftmp1], %[ftmp10] \n\t"
"packushb %[ftmp1], %[ftmp1], %[ftmp10] \n\t"
"pmaxsh %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
"packushb %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
"pmaxsh %[ftmp3], %[ftmp3], %[ftmp10] \n\t"
"packushb %[ftmp3], %[ftmp3], %[ftmp10] \n\t"
"pmaxsh %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
"packushb %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
"pmaxsh %[ftmp5], %[ftmp5], %[ftmp10] \n\t"
"packushb %[ftmp5], %[ftmp5], %[ftmp10] \n\t"
"pmaxsh %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
"packushb %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
"pmaxsh %[ftmp7], %[ftmp7], %[ftmp10] \n\t"
"packushb %[ftmp7], %[ftmp7], %[ftmp10] \n\t"
"swc1 %[ftmp0], 0x00(%[dst]) \n\t"
PTR_ADDU "%[tmp1], %[dst], %[stride] \n\t"
"swc1 %[ftmp1], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp2], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp3], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp4], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp5], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp6], 0x00(%[tmp1]) \n\t"
PTR_ADDU "%[tmp1], %[tmp1], %[stride] \n\t"
"swc1 %[ftmp7], 0x00(%[tmp1]) \n\t"
PTR_ADDIU "%[dst], %[dst], 0x04 \n\t"
PTR_ADDIU "%[input], %[input], 0x40 \n\t"
PTR_ADDIU "%[temp_value], %[temp_value], 0x08 \n\t"
PTR_ADDIU "%[tmp0], %[tmp0], -0x01 \n\t"
"bnez %[tmp0], 1b \n\t"
: [dst]"+&r"(dst), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
[ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
[ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
[ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
[A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
[D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
[Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
[Gd]"=&f"(ftmp[21]), [input]"+&r"(input)
: [stride]"r"(stride), [temp_value]"r"(temp_value)
: "memory"
);
}
static void idct_mmi(uint8_t *dst, int stride, int16_t *input, int type)
{
idct_row_mmi(input);
if (type == 1)
idct_column_true_mmi(dst, stride, input);
else
idct_column_false_mmi(dst, stride, input);
}
void ff_vp3_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
idct_mmi(dest, line_size, block, 1);
memset(block, 0, sizeof(*block) << 6);
}
void ff_vp3_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
idct_mmi(dest, line_size, block, 2);
memset(block, 0, sizeof(*block) << 6);
}
void ff_vp3_idct_dc_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
int dc = (block[0] + 15) >> 5;
double ftmp[7];
uint64_t tmp;
__asm__ volatile (
"xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
"mtc1 %[dc], %[ftmp5] \n\t"
"pshufh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
"li %[tmp0], 0x08 \n\t"
"1: \n\t"
"ldc1 %[ftmp1], 0x00(%[dest]) \n\t"
"punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t"
"punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t"
"paddh %[ftmp4], %[ftmp2], %[ftmp5] \n\t"
"paddh %[ftmp6], %[ftmp3], %[ftmp5] \n\t"
"packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
"packushb %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
"swc1 %[ftmp4], 0x00(%[dest]) \n\t"
"swc1 %[ftmp6], 0x04(%[dest]) \n\t"
PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
PTR_ADDIU "%[tmp0], %[tmp0], -0x01 \n\t"
"bnez %[tmp0], 1b \n\t"
: [dest]"+&r"(dest), [block]"+&r"(block), [tmp0]"=&r"(tmp),
[ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
[ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
[ftmp6]"=&f"(ftmp[6])
: [line_size]"r"(line_size), [dc]"r"(dc)
: "memory"
);
block[0] = 0;
}
void ff_put_no_rnd_pixels_l2_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride, int h)
{
if (h == 8) {
double ftmp[6];
uint64_t tmp[2];
__asm__ volatile (
"li %[tmp0], 0x08 \n\t"
"li %[tmp1], 0xfefefefe \n\t"
"dmtc1 %[tmp1], %[ftmp4] \n\t"
"punpcklwd %[ftmp4], %[ftmp4], %[ftmp4] \n\t"
"li %[tmp1], 0x01 \n\t"
"dmtc1 %[tmp1], %[ftmp5] \n\t"
"1: \n\t"
"gsldlc1 %[ftmp1], 0x07(%[src1]) \n\t"
"gsldrc1 %[ftmp1], 0x00(%[src1]) \n\t"
"gsldlc1 %[ftmp2], 0x07(%[src2]) \n\t"
"gsldrc1 %[ftmp2], 0x00(%[src2]) \n\t"
"xor %[ftmp3], %[ftmp1], %[ftmp2] \n\t"
"and %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
"psrlw %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
"and %[ftmp6], %[ftmp1], %[ftmp2] \n\t"
"paddw %[ftmp3], %[ftmp3], %[ftmp6] \n\t"
"sdc1 %[ftmp3], 0x00(%[dst]) \n\t"
PTR_ADDU "%[src1], %[src1], %[stride] \n\t"
PTR_ADDU "%[src2], %[src2], %[stride] \n\t"
PTR_ADDU "%[dst], %[dst], %[stride] \n\t"
PTR_ADDIU "%[tmp0], %[tmp0], -0x01 \n\t"
"bnez %[tmp0], 1b \n\t"
: [dst]"+&r"(dst), [src1]"+&r"(src1), [src2]"+&r"(src2),
[ftmp1]"=&f"(ftmp[0]), [ftmp2]"=&f"(ftmp[1]), [ftmp3]"=&f"(ftmp[2]),
[ftmp4]"=&f"(ftmp[3]), [ftmp5]"=&f"(ftmp[4]), [ftmp6]"=&f"(ftmp[5]),
[tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1])
: [stride]"r"(stride)
: "memory"
);
} else {
int i;
for (i = 0; i < h; i++) {
uint32_t a, b;
a = AV_RN32(&src1[i * stride]);
b = AV_RN32(&src2[i * stride]);
AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
a = AV_RN32(&src1[i * stride + 4]);
b = AV_RN32(&src2[i * stride + 4]);
AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
}
}
}

View File

@@ -0,0 +1,598 @@
/*
* Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vp3dsp_mips.h"
#include "libavutil/mips/generic_macros_msa.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/rnd_avg.h"
static void idct_msa(uint8_t *dst, int stride, int16_t *input, int type)
{
v8i16 r0, r1, r2, r3, r4, r5, r6, r7, sign;
v4i32 r0_r, r0_l, r1_r, r1_l, r2_r, r2_l, r3_r, r3_l,
r4_r, r4_l, r5_r, r5_l, r6_r, r6_l, r7_r, r7_l;
v4i32 A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
v4i32 Ed, Gd, Add, Bdd, Fd, Hd;
v16u8 sign_l;
v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
v4i32 c0, c1, c2, c3, c4, c5, c6, c7;
v4i32 f0, f1, f2, f3, f4, f5, f6, f7;
v4i32 sign_t;
v16i8 zero = {0};
v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
v4i32 cnst64277w = {64277, 64277, 64277, 64277};
v4i32 cnst60547w = {60547, 60547, 60547, 60547};
v4i32 cnst54491w = {54491, 54491, 54491, 54491};
v4i32 cnst46341w = {46341, 46341, 46341, 46341};
v4i32 cnst36410w = {36410, 36410, 36410, 36410};
v4i32 cnst25080w = {25080, 25080, 25080, 25080};
v4i32 cnst12785w = {12785, 12785, 12785, 12785};
v4i32 cnst8w = {8, 8, 8, 8};
v4i32 cnst2048w = {2048, 2048, 2048, 2048};
v4i32 cnst128w = {128, 128, 128, 128};
/* Extended input data */
LD_SH8(input, 8, r0, r1, r2, r3, r4, r5, r6, r7);
sign = __msa_clti_s_h(r0, 0);
r0_r = (v4i32) __msa_ilvr_h(sign, r0);
r0_l = (v4i32) __msa_ilvl_h(sign, r0);
sign = __msa_clti_s_h(r1, 0);
r1_r = (v4i32) __msa_ilvr_h(sign, r1);
r1_l = (v4i32) __msa_ilvl_h(sign, r1);
sign = __msa_clti_s_h(r2, 0);
r2_r = (v4i32) __msa_ilvr_h(sign, r2);
r2_l = (v4i32) __msa_ilvl_h(sign, r2);
sign = __msa_clti_s_h(r3, 0);
r3_r = (v4i32) __msa_ilvr_h(sign, r3);
r3_l = (v4i32) __msa_ilvl_h(sign, r3);
sign = __msa_clti_s_h(r4, 0);
r4_r = (v4i32) __msa_ilvr_h(sign, r4);
r4_l = (v4i32) __msa_ilvl_h(sign, r4);
sign = __msa_clti_s_h(r5, 0);
r5_r = (v4i32) __msa_ilvr_h(sign, r5);
r5_l = (v4i32) __msa_ilvl_h(sign, r5);
sign = __msa_clti_s_h(r6, 0);
r6_r = (v4i32) __msa_ilvr_h(sign, r6);
r6_l = (v4i32) __msa_ilvl_h(sign, r6);
sign = __msa_clti_s_h(r7, 0);
r7_r = (v4i32) __msa_ilvr_h(sign, r7);
r7_l = (v4i32) __msa_ilvl_h(sign, r7);
/* Right part */
A = ((r1_r * cnst64277w) >> 16) + ((r7_r * cnst12785w) >> 16);
B = ((r1_r * cnst12785w) >> 16) - ((r7_r * cnst64277w) >> 16);
C = ((r3_r * cnst54491w) >> 16) + ((r5_r * cnst36410w) >> 16);
D = ((r5_r * cnst54491w) >> 16) - ((r3_r * cnst36410w) >> 16);
Ad = ((A - C) * cnst46341w) >> 16;
Bd = ((B - D) * cnst46341w) >> 16;
Cd = A + C;
Dd = B + D;
E = ((r0_r + r4_r) * cnst46341w) >> 16;
F = ((r0_r - r4_r) * cnst46341w) >> 16;
G = ((r2_r * cnst60547w) >> 16) + ((r6_r * cnst25080w) >> 16);
H = ((r2_r * cnst25080w) >> 16) - ((r6_r * cnst60547w) >> 16);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
r0_r = Gd + Cd;
r7_r = Gd - Cd;
r1_r = Add + Hd;
r2_r = Add - Hd;
r3_r = Ed + Dd;
r4_r = Ed - Dd;
r5_r = Fd + Bdd;
r6_r = Fd - Bdd;
/* Left part */
A = ((r1_l * cnst64277w) >> 16) + ((r7_l * cnst12785w) >> 16);
B = ((r1_l * cnst12785w) >> 16) - ((r7_l * cnst64277w) >> 16);
C = ((r3_l * cnst54491w) >> 16) + ((r5_l * cnst36410w) >> 16);
D = ((r5_l * cnst54491w) >> 16) - ((r3_l * cnst36410w) >> 16);
Ad = ((A - C) * cnst46341w) >> 16;
Bd = ((B - D) * cnst46341w) >> 16;
Cd = A + C;
Dd = B + D;
E = ((r0_l + r4_l) * cnst46341w) >> 16;
F = ((r0_l - r4_l) * cnst46341w) >> 16;
G = ((r2_l * cnst60547w) >> 16) + ((r6_l * cnst25080w) >> 16);
H = ((r2_l * cnst25080w) >> 16) - ((r6_l * cnst60547w) >> 16);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
r0_l = Gd + Cd;
r7_l = Gd - Cd;
r1_l = Add + Hd;
r2_l = Add - Hd;
r3_l = Ed + Dd;
r4_l = Ed - Dd;
r5_l = Fd + Bdd;
r6_l = Fd - Bdd;
/* Row 0 to 3 */
TRANSPOSE4x4_SW_SW(r0_r, r1_r, r2_r, r3_r,
r0_r, r1_r, r2_r, r3_r);
TRANSPOSE4x4_SW_SW(r0_l, r1_l, r2_l, r3_l,
r0_l, r1_l, r2_l, r3_l);
A = ((r1_r * cnst64277w) >> 16) + ((r3_l * cnst12785w) >> 16);
B = ((r1_r * cnst12785w) >> 16) - ((r3_l * cnst64277w) >> 16);
C = ((r3_r * cnst54491w) >> 16) + ((r1_l * cnst36410w) >> 16);
D = ((r1_l * cnst54491w) >> 16) - ((r3_r * cnst36410w) >> 16);
Ad = ((A - C) * cnst46341w) >> 16;
Bd = ((B - D) * cnst46341w) >> 16;
Cd = A + C;
Dd = B + D;
E = ((r0_r + r0_l) * cnst46341w) >> 16;
E += cnst8w;
F = ((r0_r - r0_l) * cnst46341w) >> 16;
F += cnst8w;
if (type == 1) { // HACK
E += cnst2048w;
F += cnst2048w;
}
G = ((r2_r * cnst60547w) >> 16) + ((r2_l * cnst25080w) >> 16);
H = ((r2_r * cnst25080w) >> 16) - ((r2_l * cnst60547w) >> 16);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
A = (Gd + Cd) >> 4;
B = (Gd - Cd) >> 4;
C = (Add + Hd) >> 4;
D = (Add - Hd) >> 4;
E = (Ed + Dd) >> 4;
F = (Ed - Dd) >> 4;
G = (Fd + Bdd) >> 4;
H = (Fd - Bdd) >> 4;
if (type != 1) {
LD_SB8(dst, stride, d0, d1, d2, d3, d4, d5, d6, d7);
ILVR_B4_SW(zero, d0, zero, d1, zero, d2, zero, d3,
f0, f1, f2, f3);
ILVR_B4_SW(zero, d4, zero, d5, zero, d6, zero, d7,
f4, f5, f6, f7);
ILVR_H4_SW(zero, f0, zero, f1, zero, f2, zero, f3,
c0, c1, c2, c3);
ILVR_H4_SW(zero, f4, zero, f5, zero, f6, zero, f7,
c4, c5, c6, c7);
A += c0;
B += c7;
C += c1;
D += c2;
E += c3;
F += c4;
G += c5;
H += c6;
}
CLIP_SW8_0_255(A, B, C, D, E, F, G, H);
sign_l = __msa_or_v((v16u8)r1_r, (v16u8)r2_r);
sign_l = __msa_or_v(sign_l, (v16u8)r3_r);
sign_l = __msa_or_v(sign_l, (v16u8)r0_l);
sign_l = __msa_or_v(sign_l, (v16u8)r1_l);
sign_l = __msa_or_v(sign_l, (v16u8)r2_l);
sign_l = __msa_or_v(sign_l, (v16u8)r3_l);
sign_t = __msa_ceqi_w((v4i32)sign_l, 0);
Add = ((r0_r * cnst46341w) + (8 << 16)) >> 20;
if (type == 1) {
Bdd = Add + cnst128w;
CLIP_SW_0_255(Bdd);
Ad = Bdd;
Bd = Bdd;
Cd = Bdd;
Dd = Bdd;
Ed = Bdd;
Fd = Bdd;
Gd = Bdd;
Hd = Bdd;
} else {
Ad = Add + c0;
Bd = Add + c1;
Cd = Add + c2;
Dd = Add + c3;
Ed = Add + c4;
Fd = Add + c5;
Gd = Add + c6;
Hd = Add + c7;
CLIP_SW8_0_255(Ad, Bd, Cd, Dd, Ed, Fd, Gd, Hd);
}
Ad = (v4i32)__msa_and_v((v16u8)Ad, (v16u8)sign_t);
Bd = (v4i32)__msa_and_v((v16u8)Bd, (v16u8)sign_t);
Cd = (v4i32)__msa_and_v((v16u8)Cd, (v16u8)sign_t);
Dd = (v4i32)__msa_and_v((v16u8)Dd, (v16u8)sign_t);
Ed = (v4i32)__msa_and_v((v16u8)Ed, (v16u8)sign_t);
Fd = (v4i32)__msa_and_v((v16u8)Fd, (v16u8)sign_t);
Gd = (v4i32)__msa_and_v((v16u8)Gd, (v16u8)sign_t);
Hd = (v4i32)__msa_and_v((v16u8)Hd, (v16u8)sign_t);
sign_t = __msa_ceqi_w(sign_t, 0);
A = (v4i32)__msa_and_v((v16u8)A, (v16u8)sign_t);
B = (v4i32)__msa_and_v((v16u8)B, (v16u8)sign_t);
C = (v4i32)__msa_and_v((v16u8)C, (v16u8)sign_t);
D = (v4i32)__msa_and_v((v16u8)D, (v16u8)sign_t);
E = (v4i32)__msa_and_v((v16u8)E, (v16u8)sign_t);
F = (v4i32)__msa_and_v((v16u8)F, (v16u8)sign_t);
G = (v4i32)__msa_and_v((v16u8)G, (v16u8)sign_t);
H = (v4i32)__msa_and_v((v16u8)H, (v16u8)sign_t);
r0_r = Ad + A;
r1_r = Bd + C;
r2_r = Cd + D;
r3_r = Dd + E;
r0_l = Ed + F;
r1_l = Fd + G;
r2_l = Gd + H;
r3_l = Hd + B;
/* Row 4 to 7 */
TRANSPOSE4x4_SW_SW(r4_r, r5_r, r6_r, r7_r,
r4_r, r5_r, r6_r, r7_r);
TRANSPOSE4x4_SW_SW(r4_l, r5_l, r6_l, r7_l,
r4_l, r5_l, r6_l, r7_l);
A = ((r5_r * cnst64277w) >> 16) + ((r7_l * cnst12785w) >> 16);
B = ((r5_r * cnst12785w) >> 16) - ((r7_l * cnst64277w) >> 16);
C = ((r7_r * cnst54491w) >> 16) + ((r5_l * cnst36410w) >> 16);
D = ((r5_l * cnst54491w) >> 16) - ((r7_r * cnst36410w) >> 16);
Ad = ((A - C) * cnst46341w) >> 16;
Bd = ((B - D) * cnst46341w) >> 16;
Cd = A + C;
Dd = B + D;
E = ((r4_r + r4_l) * cnst46341w) >> 16;
E += cnst8w;
F = ((r4_r - r4_l) * cnst46341w) >> 16;
F += cnst8w;
if (type == 1) { // HACK
E += cnst2048w;
F += cnst2048w;
}
G = ((r6_r * cnst60547w) >> 16) + ((r6_l * cnst25080w) >> 16);
H = ((r6_r * cnst25080w) >> 16) - ((r6_l * cnst60547w) >> 16);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
A = (Gd + Cd) >> 4;
B = (Gd - Cd) >> 4;
C = (Add + Hd) >> 4;
D = (Add - Hd) >> 4;
E = (Ed + Dd) >> 4;
F = (Ed - Dd) >> 4;
G = (Fd + Bdd) >> 4;
H = (Fd - Bdd) >> 4;
if (type != 1) {
ILVL_H4_SW(zero, f0, zero, f1, zero, f2, zero, f3,
c0, c1, c2, c3);
ILVL_H4_SW(zero, f4, zero, f5, zero, f6, zero, f7,
c4, c5, c6, c7);
A += c0;
B += c7;
C += c1;
D += c2;
E += c3;
F += c4;
G += c5;
H += c6;
}
CLIP_SW8_0_255(A, B, C, D, E, F, G, H);
sign_l = __msa_or_v((v16u8)r5_r, (v16u8)r6_r);
sign_l = __msa_or_v(sign_l, (v16u8)r7_r);
sign_l = __msa_or_v(sign_l, (v16u8)r4_l);
sign_l = __msa_or_v(sign_l, (v16u8)r5_l);
sign_l = __msa_or_v(sign_l, (v16u8)r6_l);
sign_l = __msa_or_v(sign_l, (v16u8)r7_l);
sign_t = __msa_ceqi_w((v4i32)sign_l, 0);
Add = ((r4_r * cnst46341w) + (8 << 16)) >> 20;
if (type == 1) {
Bdd = Add + cnst128w;
CLIP_SW_0_255(Bdd);
Ad = Bdd;
Bd = Bdd;
Cd = Bdd;
Dd = Bdd;
Ed = Bdd;
Fd = Bdd;
Gd = Bdd;
Hd = Bdd;
} else {
Ad = Add + c0;
Bd = Add + c1;
Cd = Add + c2;
Dd = Add + c3;
Ed = Add + c4;
Fd = Add + c5;
Gd = Add + c6;
Hd = Add + c7;
CLIP_SW8_0_255(Ad, Bd, Cd, Dd, Ed, Fd, Gd, Hd);
}
Ad = (v4i32)__msa_and_v((v16u8)Ad, (v16u8)sign_t);
Bd = (v4i32)__msa_and_v((v16u8)Bd, (v16u8)sign_t);
Cd = (v4i32)__msa_and_v((v16u8)Cd, (v16u8)sign_t);
Dd = (v4i32)__msa_and_v((v16u8)Dd, (v16u8)sign_t);
Ed = (v4i32)__msa_and_v((v16u8)Ed, (v16u8)sign_t);
Fd = (v4i32)__msa_and_v((v16u8)Fd, (v16u8)sign_t);
Gd = (v4i32)__msa_and_v((v16u8)Gd, (v16u8)sign_t);
Hd = (v4i32)__msa_and_v((v16u8)Hd, (v16u8)sign_t);
sign_t = __msa_ceqi_w(sign_t, 0);
A = (v4i32)__msa_and_v((v16u8)A, (v16u8)sign_t);
B = (v4i32)__msa_and_v((v16u8)B, (v16u8)sign_t);
C = (v4i32)__msa_and_v((v16u8)C, (v16u8)sign_t);
D = (v4i32)__msa_and_v((v16u8)D, (v16u8)sign_t);
E = (v4i32)__msa_and_v((v16u8)E, (v16u8)sign_t);
F = (v4i32)__msa_and_v((v16u8)F, (v16u8)sign_t);
G = (v4i32)__msa_and_v((v16u8)G, (v16u8)sign_t);
H = (v4i32)__msa_and_v((v16u8)H, (v16u8)sign_t);
r4_r = Ad + A;
r5_r = Bd + C;
r6_r = Cd + D;
r7_r = Dd + E;
r4_l = Ed + F;
r5_l = Fd + G;
r6_l = Gd + H;
r7_l = Hd + B;
VSHF_B2_SB(r0_r, r4_r, r1_r, r5_r, mask, mask, d0, d1);
VSHF_B2_SB(r2_r, r6_r, r3_r, r7_r, mask, mask, d2, d3);
VSHF_B2_SB(r0_l, r4_l, r1_l, r5_l, mask, mask, d4, d5);
VSHF_B2_SB(r2_l, r6_l, r3_l, r7_l, mask, mask, d6, d7);
/* Final sequence of operations over-write original dst */
ST_D1(d0, 0, dst);
ST_D1(d1, 0, dst + stride);
ST_D1(d2, 0, dst + 2 * stride);
ST_D1(d3, 0, dst + 3 * stride);
ST_D1(d4, 0, dst + 4 * stride);
ST_D1(d5, 0, dst + 5 * stride);
ST_D1(d6, 0, dst + 6 * stride);
ST_D1(d7, 0, dst + 7 * stride);
}
void ff_vp3_idct_put_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
idct_msa(dest, line_size, block, 1);
memset(block, 0, sizeof(*block) * 64);
}
void ff_vp3_idct_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
idct_msa(dest, line_size, block, 2);
memset(block, 0, sizeof(*block) * 64);
}
void ff_vp3_idct_dc_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
{
int i = (block[0] + 15) >> 5;
v4i32 dc = {i, i, i, i};
v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
v4i32 c0, c1, c2, c3, c4, c5, c6, c7;
v4i32 e0, e1, e2, e3, e4, e5, e6, e7;
v4i32 r0, r1, r2, r3, r4, r5, r6, r7;
v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
v16i8 zero = {0};
LD_SB8(dest, line_size, d0, d1, d2, d3, d4, d5, d6, d7);
ILVR_B4_SW(zero, d0, zero, d1, zero, d2, zero, d3,
c0, c1, c2, c3);
ILVR_B4_SW(zero, d4, zero, d5, zero, d6, zero, d7,
c4, c5, c6, c7);
/* Right part */
ILVR_H4_SW(zero, c0, zero, c1, zero, c2, zero, c3,
e0, e1, e2, e3);
ILVR_H4_SW(zero, c4, zero, c5, zero, c6, zero, c7,
e4, e5, e6, e7);
e0 += dc;
e1 += dc;
e2 += dc;
e3 += dc;
e4 += dc;
e5 += dc;
e6 += dc;
e7 += dc;
CLIP_SW8_0_255(e0, e1, e2, e3, e4, e5, e6, e7);
/* Left part */
ILVL_H4_SW(zero, c0, zero, c1, zero, c2, zero, c3,
r0, r1, r2, r3);
ILVL_H4_SW(zero, c4, zero, c5, zero, c6, zero, c7,
r4, r5, r6, r7);
r0 += dc;
r1 += dc;
r2 += dc;
r3 += dc;
r4 += dc;
r5 += dc;
r6 += dc;
r7 += dc;
CLIP_SW8_0_255(r0, r1, r2, r3, r4, r5, r6, r7);
VSHF_B2_SB(e0, r0, e1, r1, mask, mask, d0, d1);
VSHF_B2_SB(e2, r2, e3, r3, mask, mask, d2, d3);
VSHF_B2_SB(e4, r4, e5, r5, mask, mask, d4, d5);
VSHF_B2_SB(e6, r6, e7, r7, mask, mask, d6, d7);
/* Final sequence of operations over-write original dst */
ST_D1(d0, 0, dest);
ST_D1(d1, 0, dest + line_size);
ST_D1(d2, 0, dest + 2 * line_size);
ST_D1(d3, 0, dest + 3 * line_size);
ST_D1(d4, 0, dest + 4 * line_size);
ST_D1(d5, 0, dest + 5 * line_size);
ST_D1(d6, 0, dest + 6 * line_size);
ST_D1(d7, 0, dest + 7 * line_size);
block[0] = 0;
}
void ff_vp3_v_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
int *bounding_values)
{
int nstride = -stride;
v4i32 e0, e1, f0, f1, g0, g1;
v16i8 zero = {0};
v16i8 d0, d1, d2, d3;
v8i16 c0, c1, c2, c3;
v8i16 r0;
v8i16 cnst3h = {3, 3, 3, 3, 3, 3, 3, 3},
cnst4h = {4, 4, 4, 4, 4, 4, 4, 4};
v16i8 mask = {0, 4, 8, 12, 16, 20, 24, 28, 0, 0, 0, 0, 0, 0, 0, 0};
int16_t temp_16[8];
int temp_32[8];
LD_SB4(first_pixel + nstride * 2, stride, d0, d1, d2, d3);
ILVR_B4_SH(zero, d0, zero, d1, zero, d2, zero, d3,
c0, c1, c2, c3);
r0 = (c0 - c3) + (c2 - c1) * cnst3h;
r0 += cnst4h;
r0 = r0 >> 3;
/* Get filter_value from bounding_values one by one */
ST_SH(r0, temp_16);
for (int i = 0; i < 8; i++)
temp_32[i] = bounding_values[temp_16[i]];
LD_SW2(temp_32, 4, e0, e1);
ILVR_H2_SW(zero, c1, zero, c2, f0, g0);
ILVL_H2_SW(zero, c1, zero, c2, f1, g1);
f0 += e0;
f1 += e1;
g0 -= e0;
g1 -= e1;
CLIP_SW4_0_255(f0, f1, g0, g1);
VSHF_B2_SB(f0, f1, g0, g1, mask, mask, d1, d2);
/* Final move to first_pixel */
ST_D1(d1, 0, first_pixel + nstride);
ST_D1(d2, 0, first_pixel);
}
void ff_vp3_h_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
int *bounding_values)
{
v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
v8i16 c0, c1, c2, c3, c4, c5, c6, c7;
v8i16 r0;
v4i32 e0, e1, f0, f1, g0, g1;
v16i8 zero = {0};
v8i16 cnst3h = {3, 3, 3, 3, 3, 3, 3, 3},
cnst4h = {4, 4, 4, 4, 4, 4, 4, 4};
v16i8 mask = {0, 16, 4, 20, 8, 24, 12, 28, 0, 0, 0, 0, 0, 0, 0, 0};
int16_t temp_16[8];
int temp_32[8];
LD_SB8(first_pixel - 2, stride, d0, d1, d2, d3, d4, d5, d6, d7);
ILVR_B4_SH(zero, d0, zero, d1, zero, d2, zero, d3,
c0, c1, c2, c3);
ILVR_B4_SH(zero, d4, zero, d5, zero, d6, zero, d7,
c4, c5, c6, c7);
TRANSPOSE8x8_SH_SH(c0, c1, c2, c3, c4, c5, c6, c7,
c0, c1, c2, c3, c4, c5, c6, c7);
r0 = (c0 - c3) + (c2 - c1) * cnst3h;
r0 += cnst4h;
r0 = r0 >> 3;
/* Get filter_value from bounding_values one by one */
ST_SH(r0, temp_16);
for (int i = 0; i < 8; i++)
temp_32[i] = bounding_values[temp_16[i]];
LD_SW2(temp_32, 4, e0, e1);
ILVR_H2_SW(zero, c1, zero, c2, f0, g0);
ILVL_H2_SW(zero, c1, zero, c2, f1, g1);
f0 += e0;
f1 += e1;
g0 -= e0;
g1 -= e1;
CLIP_SW4_0_255(f0, f1, g0, g1);
VSHF_B2_SB(f0, g0, f1, g1, mask, mask, d1, d2);
/* Final move to first_pixel */
ST_H4(d1, 0, 1, 2, 3, first_pixel - 1, stride);
ST_H4(d2, 0, 1, 2, 3, first_pixel - 1 + 4 * stride, stride);
}
void ff_put_no_rnd_pixels_l2_msa(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride, int h)
{
if (h == 8) {
v16i8 d0, d1, d2, d3, d4, d5, d6, d7;
v16i8 c0, c1, c2, c3;
v4i32 a0, a1, a2, a3, b0, b1, b2, b3;
v4i32 e0, e1, e2;
v4i32 f0, f1, f2;
v4u32 t0, t1, t2, t3;
v16i8 mask = {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23};
int32_t value = 0xfefefefe;
v4i32 fmask = {value, value, value, value};
LD_SB8(src1, stride, d0, d1, d2, d3, d4, d5, d6, d7);
VSHF_B2_SB(d0, d1, d2, d3, mask, mask, c0, c1);
VSHF_B2_SB(d4, d5, d6, d7, mask, mask, c2, c3);
a0 = (v4i32) __msa_pckev_d((v2i64)c1, (v2i64)c0);
a2 = (v4i32) __msa_pckod_d((v2i64)c1, (v2i64)c0);
a1 = (v4i32) __msa_pckev_d((v2i64)c3, (v2i64)c2);
a3 = (v4i32) __msa_pckod_d((v2i64)c3, (v2i64)c2);
LD_SB8(src2, stride, d0, d1, d2, d3, d4, d5, d6, d7);
VSHF_B2_SB(d0, d1, d2, d3, mask, mask, c0, c1);
VSHF_B2_SB(d4, d5, d6, d7, mask, mask, c2, c3);
b0 = (v4i32) __msa_pckev_d((v2i64)c1, (v2i64)c0);
b2 = (v4i32) __msa_pckod_d((v2i64)c1, (v2i64)c0);
b1 = (v4i32) __msa_pckev_d((v2i64)c3, (v2i64)c2);
b3 = (v4i32) __msa_pckod_d((v2i64)c3, (v2i64)c2);
e0 = (v4i32) __msa_xor_v((v16u8)a0, (v16u8)b0);
e0 = (v4i32) __msa_and_v((v16u8)e0, (v16u8)fmask);
t0 = ((v4u32)e0) >> 1;
e2 = (v4i32) __msa_and_v((v16u8)a0, (v16u8)b0);
t0 = t0 + (v4u32)e2;
e1 = (v4i32) __msa_xor_v((v16u8)a1, (v16u8)b1);
e1 = (v4i32) __msa_and_v((v16u8)e1, (v16u8)fmask);
t1 = ((v4u32)e1) >> 1;
e2 = (v4i32) __msa_and_v((v16u8)a1, (v16u8)b1);
t1 = t1 + (v4u32)e2;
f0 = (v4i32) __msa_xor_v((v16u8)a2, (v16u8)b2);
f0 = (v4i32) __msa_and_v((v16u8)f0, (v16u8)fmask);
t2 = ((v4u32)f0) >> 1;
f2 = (v4i32) __msa_and_v((v16u8)a2, (v16u8)b2);
t2 = t2 + (v4u32)f2;
f1 = (v4i32) __msa_xor_v((v16u8)a3, (v16u8)b3);
f1 = (v4i32) __msa_and_v((v16u8)f1, (v16u8)fmask);
t3 = ((v4u32)f1) >> 1;
f2 = (v4i32) __msa_and_v((v16u8)a3, (v16u8)b3);
t3 = t3 + (v4u32)f2;
ST_W8(t0, t1, 0, 1, 2, 3, 0, 1, 2, 3, dst, stride);
ST_W8(t2, t3, 0, 1, 2, 3, 0, 1, 2, 3, dst + 4, stride);
} else {
int i;
for (i = 0; i < h; i++) {
uint32_t a, b;
a = AV_RN32(&src1[i * stride]);
b = AV_RN32(&src2[i * stride]);
AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
a = AV_RN32(&src1[i * stride + 4]);
b = AV_RN32(&src2[i * stride + 4]);
AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
}
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/vp3dsp.h"
#include "vp3dsp_mips.h"
#if HAVE_MSA
static av_cold void vp3dsp_init_msa(VP3DSPContext *c, int flags)
{
c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_msa;
c->idct_add = ff_vp3_idct_add_msa;
c->idct_put = ff_vp3_idct_put_msa;
c->idct_dc_add = ff_vp3_idct_dc_add_msa;
c->v_loop_filter = ff_vp3_v_loop_filter_msa;
c->h_loop_filter = ff_vp3_h_loop_filter_msa;
}
#endif /* HAVE_MSA */
#if HAVE_MMI
static av_cold void vp3dsp_init_mmi(VP3DSPContext *c, int flags)
{
c->put_no_rnd_pixels_l2 = ff_put_no_rnd_pixels_l2_mmi;
c->idct_add = ff_vp3_idct_add_mmi;
c->idct_put = ff_vp3_idct_put_mmi;
c->idct_dc_add = ff_vp3_idct_dc_add_mmi;
}
#endif /* HAVE_MMI */
av_cold void ff_vp3dsp_init_mips(VP3DSPContext *c, int flags)
{
#if HAVE_MMI
vp3dsp_init_mmi(c, flags);
#endif /* HAVE_MMI */
#if HAVE_MSA
vp3dsp_init_msa(c, flags);
#endif /* HAVE_MSA */
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MIPS_VP3DSP_MIPS_H
#define AVCODEC_MIPS_VP3DSP_MIPS_H
#include "libavcodec/vp3dsp.h"
#include <string.h>
void ff_vp3_idct_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_vp3_idct_put_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_vp3_idct_dc_add_msa(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_vp3_v_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
int *bounding_values);
void ff_put_no_rnd_pixels_l2_msa(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride, int h);
void ff_vp3_h_loop_filter_msa(uint8_t *first_pixel, ptrdiff_t stride,
int *bounding_values);
void ff_vp3_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_vp3_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_vp3_idct_dc_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
void ff_put_no_rnd_pixels_l2_mmi(uint8_t *dst, const uint8_t *src1,
const uint8_t *src2, ptrdiff_t stride, int h);
#endif /* #ifndef AVCODEC_MIPS_VP3DSP_MIPS_H */

Some files were not shown because too many files have changed in this diff Show More