ffmpeg-devel
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
October 2016
- 125 participants
- 351 discussions
22 Dec '16
From: Jan Sebechlebsky <sebechlebskyjan(a)gmail.com>
Signed-off-by: Jan Sebechlebsky <sebechlebskyjan(a)gmail.com>
---
Thanks for noticing, I've fixed the patch
(also some minor formatting issues I've noticed).
doc/muxers.texi | 20 +++++++++++++
libavformat/tee.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index dbe53f5..7b4e165 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1473,6 +1473,7 @@ Specify whether to remove all fragments when finished. Default 0 (do not remove)
@end table
+@anchor{fifo}
@section fifo
The fifo pseudo-muxer allows the separation of encoding and muxing by using
@@ -1580,6 +1581,18 @@ with the tee muxer; encoding can be a very expensive process. It is not
useful when using the libavformat API directly because it is then possible
to feed the same packets to several muxers directly.
+@table @option
+
+@item use_fifo @var{bool}
+If set to 1, slave outputs will be processed in separate thread using @ref{fifo}
+muxer. This allows to compensate for different speed/latency/reliability of
+outputs and setup transparent recovery. By default this feature is turned off.
+
+@item fifo_options
+Options to pass to fifo pseudo-muxer instances. See @ref{fifo}.
+
+@end table
+
The slave outputs are specified in the file name given to the muxer,
separated by '|'. If any of the slave name contains the '|' separator,
leading or trailing spaces or any special character, it must be
@@ -1601,6 +1614,13 @@ output name suffix.
Specify a list of bitstream filters to apply to the specified
output.
+@item use_fifo @var{bool}
+This allows to override tee muxer use_fifo option for individual slave muxer.
+
+@item fifo_options
+This allows to override tee muxer fifo_options for individual slave muxer.
+See @ref{fifo}.
+
It is possible to specify to which streams a given bitstream filter
applies, by appending a stream specifier to the option separated by
@code{/}. @var{spec} must be a stream specifier (see @ref{Format
diff --git a/libavformat/tee.c b/libavformat/tee.c
index d59ad4d..c668e95 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -40,6 +40,8 @@ typedef struct {
AVBSFContext **bsfs; ///< bitstream filters per stream
SlaveFailurePolicy on_fail;
+ int use_fifo;
+ AVDictionary *fifo_options;
/** map from input to output streams indexes,
* disabled output streams are set to -1 */
@@ -52,15 +54,28 @@ typedef struct TeeContext {
unsigned nb_slaves;
unsigned nb_alive;
TeeSlave *slaves;
+ int use_fifo;
+ AVDictionary *fifo_options;
+ char *fifo_options_str;
} TeeContext;
static const char *const slave_delim = "|";
static const char *const slave_bsfs_spec_sep = "/";
static const char *const slave_select_sep = ",";
+#define OFFSET(x) offsetof(TeeContext, x)
+static const AVOption options[] = {
+ {"use_fifo", "Use fifo pseudo-muxer to separate actual muxers from encoder",
+ OFFSET(use_fifo), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ {"fifo_options", "fifo pseudo-muxer options", OFFSET(fifo_options_str),
+ AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
+ {NULL}
+};
+
static const AVClass tee_muxer_class = {
.class_name = "Tee muxer",
.item_name = av_default_item_name,
+ .option = options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -81,6 +96,27 @@ static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *t
return AVERROR(EINVAL);
}
+static int parse_slave_fifo_options(const char *use_fifo,
+ const char *fifo_options, TeeSlave *tee_slave)
+{
+ int ret = 0;
+
+ if (use_fifo) {
+ if (av_match_name(use_fifo, "true,y,yes,enable,enabled,on,1")) {
+ tee_slave->use_fifo = 1;
+ } else if (av_match_name(use_fifo, "false,n,no,disable,disabled,off,0")) {
+ tee_slave->use_fifo = 0;
+ } else {
+ return AVERROR(EINVAL);
+ }
+ }
+
+ if (fifo_options)
+ ret = av_dict_parse_string(&tee_slave->fifo_options, fifo_options, "=", ":", 0);
+
+ return ret;
+}
+
static int close_slave(TeeSlave *tee_slave)
{
AVFormatContext *avf;
@@ -125,6 +161,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
AVDictionaryEntry *entry;
char *filename;
char *format = NULL, *select = NULL, *on_fail = NULL;
+ char *use_fifo = NULL, *fifo_options_str = NULL;
AVFormatContext *avf2 = NULL;
AVStream *st, *st2;
int stream_count;
@@ -145,6 +182,8 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
STEAL_OPTION("f", format);
STEAL_OPTION("select", select);
STEAL_OPTION("onfail", on_fail);
+ STEAL_OPTION("use_fifo", use_fifo);
+ STEAL_OPTION("fifo_options", fifo_options_str);
ret = parse_slave_failure_policy_option(on_fail, tee_slave);
if (ret < 0) {
@@ -153,7 +192,41 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
goto end;
}
- ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
+ ret = parse_slave_fifo_options(use_fifo, fifo_options_str, tee_slave);
+ if (ret < 0) {
+ av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", av_err2str(ret));
+ goto end;
+ }
+
+ if (tee_slave->use_fifo) {
+
+ if (options) {
+ char *format_options_str = NULL;
+ ret = av_dict_get_string(options, &format_options_str, '=', ':');
+ if (ret < 0)
+ goto end;
+
+ ret = av_dict_set(&tee_slave->fifo_options, "format_options", format_options_str,
+ AV_DICT_DONT_STRDUP_VAL);
+ if (ret < 0)
+ goto end;
+ }
+
+ if (format) {
+ ret = av_dict_set(&tee_slave->fifo_options, "fifo_format", format,
+ AV_DICT_DONT_STRDUP_VAL);
+ format = NULL;
+ if (ret < 0)
+ goto end;
+ }
+
+ av_dict_free(&options);
+ options = tee_slave->fifo_options;
+
+ ret = avformat_alloc_output_context2(&avf2, NULL, "fifo", filename);
+ } else {
+ ret = avformat_alloc_output_context2(&avf2, NULL, format, filename);
+ }
if (ret < 0)
goto end;
tee_slave->avf = avf2;
@@ -394,6 +467,12 @@ static int tee_write_header(AVFormatContext *avf)
filename++;
}
+ if (tee->fifo_options_str) {
+ ret = av_dict_parse_string(&tee->fifo_options, tee->fifo_options_str, "=", ":", 0);
+ if (ret < 0)
+ goto fail;
+ }
+
if (!(tee->slaves = av_mallocz_array(nb_slaves, sizeof(*tee->slaves)))) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -401,6 +480,12 @@ static int tee_write_header(AVFormatContext *avf)
tee->nb_slaves = tee->nb_alive = nb_slaves;
for (i = 0; i < nb_slaves; i++) {
+
+ tee->slaves[i].use_fifo = tee->use_fifo;
+ ret = av_dict_copy(&tee->slaves[i].fifo_options, tee->fifo_options, 0);
+ if (ret < 0)
+ goto fail;
+
if ((ret = open_slave(avf, slaves[i], &tee->slaves[i])) < 0) {
ret = tee_process_slave_failure(avf, i, ret);
if (ret < 0)
--
1.9.1
3
6
From: Jay Ridgeway <jayridge(a)gmail.com>
Support url_get_file_handle on TLS streams.
---
libavformat/tls_gnutls.c | 7 +++++++
libavformat/tls_openssl.c | 7 +++++++
libavformat/tls_schannel.c | 7 +++++++
libavformat/tls_securetransport.c | 7 +++++++
4 files changed, 28 insertions(+)
diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c
index 991b36b..ecc80bf 100644
--- a/libavformat/tls_gnutls.c
+++ b/libavformat/tls_gnutls.c
@@ -235,6 +235,12 @@ static int tls_write(URLContext *h, const uint8_t *buf, int size)
return print_tls_error(h, ret);
}
+static int tls_get_file_handle(URLContext *h)
+{
+ TLSContext *c = h->priv_data;
+ return ffurl_get_file_handle(c->tls_shared.tcp);
+}
+
static const AVOption options[] = {
TLS_COMMON_OPTIONS(TLSContext, tls_shared),
{ NULL }
@@ -253,6 +259,7 @@ const URLProtocol ff_tls_gnutls_protocol = {
.url_read = tls_read,
.url_write = tls_write,
.url_close = tls_close,
+ .url_get_file_handle = tls_get_file_handle,
.priv_data_size = sizeof(TLSContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class = &tls_class,
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 46eb3e6..1455392 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -283,6 +283,12 @@ static int tls_write(URLContext *h, const uint8_t *buf, int size)
return print_tls_error(h, ret);
}
+static int tls_get_file_handle(URLContext *h)
+{
+ TLSContext *c = h->priv_data;
+ return ffurl_get_file_handle(c->tls_shared.tcp);
+}
+
static const AVOption options[] = {
TLS_COMMON_OPTIONS(TLSContext, tls_shared),
{ NULL }
@@ -301,6 +307,7 @@ const URLProtocol ff_tls_openssl_protocol = {
.url_read = tls_read,
.url_write = tls_write,
.url_close = tls_close,
+ .url_get_file_handle = tls_get_file_handle,
.priv_data_size = sizeof(TLSContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class = &tls_class,
diff --git a/libavformat/tls_schannel.c b/libavformat/tls_schannel.c
index c11b7d4..065dccb 100644
--- a/libavformat/tls_schannel.c
+++ b/libavformat/tls_schannel.c
@@ -577,6 +577,12 @@ done:
return ret < 0 ? ret : outbuf[1].cbBuffer;
}
+static int tls_get_file_handle(URLContext *h)
+{
+ TLSContext *c = h->priv_data;
+ return ffurl_get_file_handle(c->tls_shared.tcp);
+}
+
static const AVOption options[] = {
TLS_COMMON_OPTIONS(TLSContext, tls_shared),
{ NULL }
@@ -595,6 +601,7 @@ const URLProtocol ff_tls_schannel_protocol = {
.url_read = tls_read,
.url_write = tls_write,
.url_close = tls_close,
+ .url_get_file_handle = tls_get_file_handle,
.priv_data_size = sizeof(TLSContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class = &tls_class,
diff --git a/libavformat/tls_securetransport.c b/libavformat/tls_securetransport.c
index 253c89c..bc8a320 100644
--- a/libavformat/tls_securetransport.c
+++ b/libavformat/tls_securetransport.c
@@ -375,6 +375,12 @@ static int tls_write(URLContext *h, const uint8_t *buf, int size)
return print_tls_error(h, ret);
}
+static int tls_get_file_handle(URLContext *h)
+{
+ TLSContext *c = h->priv_data;
+ return ffurl_get_file_handle(c->tls_shared.tcp);
+}
+
static const AVOption options[] = {
TLS_COMMON_OPTIONS(TLSContext, tls_shared),
{ NULL }
@@ -393,6 +399,7 @@ const URLProtocol ff_tls_securetransport_protocol = {
.url_read = tls_read,
.url_write = tls_write,
.url_close = tls_close,
+ .url_get_file_handle = tls_get_file_handle,
.priv_data_size = sizeof(TLSContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
.priv_data_class = &tls_class,
--
2.6.3
3
3
Hi,
patch attached.
2
5
Hi,
I have some transport streams with only one pid, containing MJPEG 2000
video. Since the PMT/PAT is missing ffmpeg is unable to decode it.
The attached patch makes ffmpeg able to guess that it does contain a
stream of jpeg 2000, but I am not sure if this is the correct approach.
Also, should LIBAVFORMAT_VERSION_MICRO and the Changelog be updated?
--
Ståle Kristoffersen
4
14
[PATCH] avfilter/af_silenceremove: add optional tone when silence is removed
by Greg Rowe 17 Dec '16
by Greg Rowe 17 Dec '16
17 Dec '16
The attached patch adds two optional parameters to af_silenceremove for the purpose of inserting a tone in place of where silence was removed. This alerts the user that silence has been trimmed from the original stream. The parameters are tone_duration which defaults to 0.0 which disables the feature and tone_hz which allows you to specify the frequency of the tone.
Thanks,
Greg
--
Greg Rowe
www.shoretel.com
3
10
[PATCH 00/21] Add timed metadata tracks, track references, channel layout
by erkki.seppala.extï¼ nokia.com 17 Dec '16
by erkki.seppala.extï¼ nokia.com 17 Dec '16
17 Dec '16
From: Erkki Seppälä <erkki.seppala.ext(a)nokia.com>
Hello,
Here is a patch set with the goal of adding the following features to
the ISO base media file format support of FFmpeg (also available at
https://github.com/nokiatech/FFmpeg/tree/timed-metadata)
* Ability to mux and demux timed metadata tracks
Timed metadata tracks have a sample descriptor describing their
contents (ie. an URI and a configuration) in the headers. The tracks
are associated with media tracks by using track references and the
samples of the metadata track can have arbitrary length in size and
time.
The sample type urim is supported. The metadata track has
codec id AV_CODEC_ID_META and its type is AVMEDIA_TYPE_DATA.
* Ability to set alternate track groups (instead of using the
automatically assigned ones)
This functionality is accessed by adding side data
AV_PKT_DATA_TRACK_ALTERNATE_GROUP to the track.
* Ability to add and retrieve any types of track reference and
ability to refere multiple tracks instead of only one
This functionality is accessed by adding/accessing side data
AV_PKT_DATA_TRACK_REFERENCES to the track.
* Ability to set advanced channel layout to tracks (the chnl box)
This functionality is separated into the following three side data:
AV_PKT_DATA_AUDIO_CHANNEL_PREDEFINED_LAYOUT for choosing a
predefined channel layout (with a list of omitted channels).
AV_PKT_DATA_AUDIO_CHANNEL_LAYOUT for setting arbitrary speaker
positions.
AV_PKT_DATA_AUDIO_CHANNEL_LAYOUT_OBJECT_STRUCTURED for indicating the
audio track has object structured audio.
* Some smaller funtionality has also been added:
av_arraydup for duplicating an array (the allocated memory block is
compatible with av_realloc).
Ability to use stream ids directly as track numbers (with option
use_stream_ids_as_track_ids).
Two examples have been added (based on their non-metadata versions)
to doc/examples on how to work with timed metadata.
-
Erkki Seppälä (21):
libavutil/mem: added av_arraydup to accompany av_realloc*_array
functions
libavformat/utils: added ability to probe AVMEDIA_TYPE_DATA format
libavformat/movenc: added ability to use original stream ids as track
ids instead of regenerating them
libavcodec: added a structure AVData for decoding timed metadata
libavformat/movenc: mov_write_ftyp_tag: write the major brand a
compatible brand
libavcodec/avcodec.h: AV_CODEC_ID_META added for timed meta data
libavcodec/metaenc: added an encoder/decoder for timed metadata
libavformat/movenc: deal with AVMEDIA_TYPE_DATA by using
AV_CODEC_ID_META
libavformat/movenc: support for multiple and client-provided track
references
libavformat/movenc: add the urim sample descriptor
libavformat/movenc, isom: support metadata in mp4 files
libavformat/mov, isom: read (multiple) track references (tag and
multiple ids)
libavformat/mov: basic support for identifying (and reading) timed
metadata
libavformat/mov: ff_mov_read_stsd_entries now deals with
AVMEDIA_TYPE_DATA
libavformat/mov: read urim metadata from meta
libavcodec/avcodec, libavformat/movenc: support embedding channel
layout to stream side data
libavcodec/avcodec, libavformat/movenc: introduced
AV_PKT_DATA_TRACK_ALTERNATE_GROUP side data for expressing alternate
groups
libavformat/movenc: mov_write_audio_tag writes the proper number of
channels, not the hardcoded 2
doc/examples/extract_timed_metadata: added a bare-bones metadata
extractor; find only the frames
doc/examples/muxing_with_metadata: example for dealing with timed meta
data
changelog: updated
Changelog | 21 +-
configure | 4 +-
doc/examples/Makefile | 3 +
doc/examples/extract_timed_metadata.c | 233 +++++++++
doc/examples/muxing_with_metadata.c | 882 ++++++++++++++++++++++++++++++++++
libavcodec/Makefile | 2 +-
libavcodec/allcodecs.c | 3 +
libavcodec/avcodec.h | 115 ++++-
libavcodec/codec_desc.c | 8 +
libavcodec/metacodec.c | 94 ++++
libavcodec/utils.c | 19 +
libavformat/isom.c | 7 +
libavformat/isom.h | 5 +
libavformat/mov.c | 238 ++++++++-
libavformat/movenc.c | 493 +++++++++++++++++--
libavformat/movenc.h | 64 ++-
libavformat/movenchint.c | 11 +-
libavformat/movmeta.h | 46 ++
libavformat/utils.c | 7 +-
libavutil/mem.c | 11 +
libavutil/mem.h | 11 +
21 files changed, 2219 insertions(+), 58 deletions(-)
create mode 100644 doc/examples/extract_timed_metadata.c
create mode 100644 doc/examples/muxing_with_metadata.c
create mode 100644 libavcodec/metacodec.c
create mode 100644 libavformat/movmeta.h
--
2.7.4
8
129
[PATCH 7/7] avcodec/mips: version 1 of vc1dsp optimizations for loongson mmi
by 周晓勇 17 Dec '16
by 周晓勇 17 Dec '16
17 Dec '16
From 1fd9812dbd80fc4d8d856378b718189f50a68a6f Mon Sep 17 00:00:00 2001
From: Zhou Xiaoyong <zhouxiaoyong(a)loongson.cn>
Date: Mon, 10 Oct 2016 15:43:49 +0800
Subject: [PATCH 7/7] avcodec/mips: version 1 of vc1dsp optimizations for
loongson mmi
---
libavcodec/mips/Makefile | 2 +
libavcodec/mips/constants.c | 4 +
libavcodec/mips/constants.h | 4 +
libavcodec/mips/vc1dsp_init_mips.c | 108 ++
libavcodec/mips/vc1dsp_mips.h | 194 ++++
libavcodec/mips/vc1dsp_mmi.c | 2081 ++++++++++++++++++++++++++++++++++++
libavcodec/vc1dsp.c | 2 +
libavcodec/vc1dsp.h | 1 +
8 files changed, 2396 insertions(+)
create mode 100644 libavcodec/mips/vc1dsp_init_mips.c
create mode 100644 libavcodec/mips/vc1dsp_mips.h
create mode 100644 libavcodec/mips/vc1dsp_mmi.c
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index 2b6f37e..b118558 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -36,6 +36,7 @@ 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_VC1_DECODER) += mips/vc1dsp_init_mips.o
OBJS-$(CONFIG_WMV2DSP) += mips/wmv2dsp_init_mips.o
MSA-OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_msa.o \
mips/hevc_mc_uni_msa.o \
@@ -80,4 +81,5 @@ 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
diff --git a/libavcodec/mips/constants.c b/libavcodec/mips/constants.c
index 9c10d29..a7c4a5c 100644
--- a/libavcodec/mips/constants.c
+++ b/libavcodec/mips/constants.c
@@ -32,9 +32,13 @@ 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};
diff --git a/libavcodec/mips/constants.h b/libavcodec/mips/constants.h
index e164ecb..2604559 100644
--- a/libavcodec/mips/constants.h
+++ b/libavcodec/mips/constants.h
@@ -33,9 +33,13 @@ 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;
diff --git a/libavcodec/mips/vc1dsp_init_mips.c b/libavcodec/mips/vc1dsp_init_mips.c
new file mode 100644
index 0000000..4adc9e1
--- /dev/null
+++ b/libavcodec/mips/vc1dsp_init_mips.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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"
+
+#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;
+
+#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
+
+ 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 */
+
+av_cold void ff_vc1dsp_init_mips(VC1DSPContext *dsp)
+{
+#if HAVE_MMI
+ vc1dsp_init_mmi(dsp);
+#endif /* HAVE_MMI */
+}
diff --git a/libavcodec/mips/vc1dsp_mips.h b/libavcodec/mips/vc1dsp_mips.h
new file mode 100644
index 0000000..2cdd900
--- /dev/null
+++ b/libavcodec/mips/vc1dsp_mips.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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, int linesize, int16_t *block);
+void ff_vc1_inv_trans_4x8_mmi(uint8_t *dest, int linesize, int16_t *block);
+void ff_vc1_inv_trans_4x4_mmi(uint8_t *dest, int linesize, int16_t *block);
+
+void ff_vc1_inv_trans_4x4_dc_mmi(uint8_t *dest, int linesize, int16_t *block);
+void ff_vc1_inv_trans_4x8_dc_mmi(uint8_t *dest, int linesize, int16_t *block);
+void ff_vc1_inv_trans_8x4_dc_mmi(uint8_t *dest, int linesize, int16_t *block);
+void ff_vc1_inv_trans_8x8_dc_mmi(uint8_t *dest, int 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);
+
+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 */,
+ int 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 */,
+ int 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 */,
+ int 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 */,
+ int stride, int h, int x, int y);
+
+#endif /* AVCODEC_MIPS_VC1DSP_MIPS_H */
diff --git a/libavcodec/mips/vc1dsp_mmi.c b/libavcodec/mips/vc1dsp_mmi.c
new file mode 100644
index 0000000..dfae2d9
--- /dev/null
+++ b/libavcodec/mips/vc1dsp_mmi.c
@@ -0,0 +1,2081 @@
+/*
+ * VC-1 and WMV3 - DSP functions Loongson MMI-optimized
+ *
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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/avassert.h"
+#include "libavcodec/vc1dsp.h"
+#include "constants.h"
+#include "vc1dsp_mips.h"
+#include "hpeldsp_mips.h"
+#include "libavutil/mips/mmiutils.h"
+
+
+#define VC1_INV_TRANCS_8_STEP1_MMI(fp1, fp2, fp3, fp4, \
+ o1, o2, o3, o4, \
+ t1, t2, t3, t4, \
+ ff_p1, ff_p2, ff_p3, ff_p4) \
+ "pmullh "#t1" , "#fp1" , "#ff_p1" \n\t" \
+ "pmullh "#t2" , "#fp2" , "#ff_p2" \n\t" \
+ "pmullh "#t3" , "#fp3" , "#ff_p3" \n\t" \
+ "pmullh "#t4" , "#fp4" , "#ff_p4" \n\t" \
+ "paddh "#o1" , "#t1" , "#t2" \n\t" \
+ "paddh "#o1" , "#o1" , "#t3" \n\t" \
+ "paddh "#o1" , "#o1" , "#t4" \n\t" \
+ \
+ "pmullh "#t1" , "#fp1" , "#ff_p2" \n\t" \
+ "pmullh "#t2" , "#fp2" , "#ff_p4" \n\t" \
+ "pmullh "#t3" , "#fp3" , "#ff_p1" \n\t" \
+ "pmullh "#t4" , "#fp4" , "#ff_p3" \n\t" \
+ "psubh "#o2" , "#t1" , "#t2" \n\t" \
+ "psubh "#o2" , "#o2" , "#t3" \n\t" \
+ "psubh "#o2" , "#o2" , "#t4" \n\t" \
+ \
+ "pmullh "#t1" , "#fp1" , "#ff_p3" \n\t" \
+ "pmullh "#t2" , "#fp2" , "#ff_p1" \n\t" \
+ "pmullh "#t3" , "#fp3" , "#ff_p4" \n\t" \
+ "pmullh "#t4" , "#fp4" , "#ff_p2" \n\t" \
+ "psubh "#o3" , "#t1" , "#t2" \n\t" \
+ "paddh "#o3" , "#o3" , "#t3" \n\t" \
+ "paddh "#o3" , "#o3" , "#t4" \n\t" \
+ \
+ "pmullh "#t1" , "#fp1" , "#ff_p4" \n\t" \
+ "pmullh "#t2" , "#fp2" , "#ff_p3" \n\t" \
+ "pmullh "#t3" , "#fp3" , "#ff_p2" \n\t" \
+ "pmullh "#t4" , "#fp4" , "#ff_p1" \n\t" \
+ "psubh "#o4" , "#t1" , "#t2" \n\t" \
+ "paddh "#o4" , "#o4" , "#t3" \n\t" \
+ "psubh "#o4" , "#o4" , "#t4" \n\t"
+
+
+#define VC1_INV_TRANCS_8_STEP2_MMI(fp1, fp2, fp3, fp4, \
+ fp5, fp6, fp7, fp8, \
+ o1, o2, o3, o4, \
+ ff_p1, ff_p2, ff_p3, ff_pw) \
+ "paddh "#fp5" , "#fp1" , "#fp2" \n\t" \
+ "psubh "#fp6" , "#fp1" , "#fp2" \n\t" \
+ "pmullh "#fp5" , "#fp5" , "#ff_p1" \n\t" \
+ "pmullh "#fp6" , "#fp6" , "#ff_p1" \n\t" \
+ "paddh "#fp5" , "#fp5" , "#ff_pw" \n\t" \
+ "paddh "#fp6" , "#fp6" , "#ff_pw" \n\t" \
+ \
+ "pmullh "#fp1" , "#fp3" , "#ff_p2" \n\t" \
+ "pmullh "#fp2" , "#fp4" , "#ff_p3" \n\t" \
+ "pmullh "#fp3" , "#fp3" , "#ff_p3" \n\t" \
+ "pmullh "#fp4" , "#fp4" , "#ff_p2" \n\t" \
+ "paddh "#fp7" , "#fp1" , "#fp2" \n\t" \
+ "psubh "#fp8" , "#fp3" , "#fp4" \n\t" \
+ \
+ "paddh "#fp1" , "#fp5" , "#fp7" \n\t" \
+ "paddh "#fp2" , "#fp6" , "#fp8" \n\t" \
+ "psubh "#fp3" , "#fp6" , "#fp8" \n\t" \
+ "psubh "#fp4" , "#fp5" , "#fp7" \n\t" \
+ \
+ "paddh "#fp5" , "#fp1" , "#o1" \n\t" \
+ "paddh "#fp6" , "#fp2" , "#o2" \n\t" \
+ "paddh "#fp7" , "#fp3" , "#o3" \n\t" \
+ "paddh "#fp8" , "#fp4" , "#o4" \n\t" \
+ \
+ "psubh "#fp4" , "#fp4" , "#o4" \n\t" \
+ "psubh "#fp3" , "#fp3" , "#o3" \n\t" \
+ "psubh "#fp2" , "#fp2" , "#o2" \n\t" \
+ "psubh "#fp1" , "#fp1" , "#o1" \n\t"
+
+
+#define VC1_INV_TRANCS_4_STEP1_MMI(fp1, fp2, fp3, fp4, \
+ fp5, fp6, fp7, fp8, \
+ ff_p1, ff_p2, ff_p3, ff_pw) \
+ "paddh "#fp5" , "#fp1" , "#fp2" \n\t" \
+ "psubh "#fp6" , "#fp1" , "#fp2" \n\t" \
+ "pmullh "#fp5" , "#fp5" , "#ff_p1" \n\t" \
+ "pmullh "#fp6" , "#fp6" , "#ff_p1" \n\t" \
+ "paddh "#fp5" , "#fp5" , "#ff_pw" \n\t" \
+ "paddh "#fp6" , "#fp6" , "#ff_pw" \n\t" \
+ \
+ "pmullh "#fp1" , "#fp3" , "#ff_p2" \n\t" \
+ "pmullh "#fp2" , "#fp4" , "#ff_p3" \n\t" \
+ "pmullh "#fp3" , "#fp3" , "#ff_p3" \n\t" \
+ "pmullh "#fp4" , "#fp4" , "#ff_p2" \n\t" \
+ "paddh "#fp7" , "#fp1" , "#fp2" \n\t" \
+ "psubh "#fp8" , "#fp3" , "#fp4" \n\t" \
+ \
+ "paddh "#fp1" , "#fp5" , "#fp7" \n\t" \
+ "psubh "#fp2" , "#fp6" , "#fp8" \n\t" \
+ "paddh "#fp3" , "#fp6" , "#fp8" \n\t" \
+ "psubh "#fp4" , "#fp5" , "#fp7" \n\t"
+
+
+#define VC1_INV_TRANCS_4_STEP2_MMI(fp1, fp2, fp3, fp4, \
+ fp5, fp6, fp7, fp8, zero) \
+ "punpcklbh "#fp5" , "#fp5" , "#zero" \n\t" \
+ "punpcklbh "#fp6" , "#fp6" , "#zero" \n\t" \
+ "punpcklbh "#fp7" , "#fp7" , "#zero" \n\t" \
+ "punpcklbh "#fp8" , "#fp8" , "#zero" \n\t" \
+ \
+ "paddh "#fp1" , "#fp1" , "#fp5" \n\t" \
+ "paddh "#fp2" , "#fp2" , "#fp6" \n\t" \
+ "paddh "#fp3" , "#fp3" , "#fp7" \n\t" \
+ "paddh "#fp4" , "#fp4" , "#fp8" \n\t" \
+ \
+ "packushb "#fp1" , "#fp1" , "#zero" \n\t" \
+ "packushb "#fp2" , "#fp2" , "#zero" \n\t" \
+ "packushb "#fp3" , "#fp3" , "#zero" \n\t" \
+ "packushb "#fp4" , "#fp4" , "#zero" \n\t"
+
+
+/* Do inverse transform on 8x8 block */
+void ff_vc1_inv_trans_8x8_dc_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int dc = block[0];
+ double ftmp[9];
+ mips_reg addr[1];
+ int count;
+
+ dc = (3 * dc + 1) >> 1;
+ dc = (3 * dc + 16) >> 5;
+
+ __asm__ volatile(
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "pshufh %[dc], %[dc], %[ftmp0] \n\t"
+ "li %[count], 0x02 \n\t"
+
+ "1: \n\t"
+ MMI_LDC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_LDC1(%[ftmp2], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LDC1(%[ftmp3], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LDC1(%[ftmp4], %[addr0], 0x00)
+
+ "punpckhbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp7], %[ftmp3], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+
+ "paddsh %[ftmp1], %[ftmp1], %[dc] \n\t"
+ "paddsh %[ftmp2], %[ftmp2], %[dc] \n\t"
+ "paddsh %[ftmp3], %[ftmp3], %[dc] \n\t"
+ "paddsh %[ftmp4], %[ftmp4], %[dc] \n\t"
+ "paddsh %[ftmp5], %[ftmp5], %[dc] \n\t"
+ "paddsh %[ftmp6], %[ftmp6], %[dc] \n\t"
+ "paddsh %[ftmp7], %[ftmp7], %[dc] \n\t"
+ "paddsh %[ftmp8], %[ftmp8], %[dc] \n\t"
+
+ "packushb %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
+
+ MMI_SDC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_SDC1(%[ftmp2], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SDC1(%[ftmp3], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SDC1(%[ftmp4], %[addr0], 0x00)
+
+ "addiu %[count], %[count], -0x01 \n\t"
+ PTR_ADDU "%[dest], %[addr0], %[linesize] \n\t"
+ "bnez %[count], 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]),
+ [addr0]"=&r"(addr[0]),
+ [count]"=&r"(count), [dest]"+&r"(dest)
+ : [linesize]"r"((mips_reg)linesize),
+ [dc]"f"(dc)
+ : "memory"
+ );
+}
+
+#if _MIPS_SIM != _ABIO32
+void ff_vc1_inv_trans_8x8_mmi(int16_t block[64])
+{
+ DECLARE_ALIGNED(16, int16_t, temp[64]);
+ int16_t *src = block;
+ int16_t *dst = temp;
+ double ftmp[16];
+ uint32_t count, tmp[1];
+
+ // 1st loop
+ __asm__ volatile (
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+ "li %[count], 0x02 \n\t"
+
+ "1: \n\t"
+ MMI_LDC1(%[ftmp5], %[src], 0x10)
+ MMI_LDC1(%[ftmp6], %[src], 0x30)
+ MMI_LDC1(%[ftmp7], %[src], 0x50)
+ MMI_LDC1(%[ftmp8], %[src], 0x70)
+
+ VC1_INV_TRANCS_8_STEP1_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ff_pw_16], %[ff_pw_15], %[ff_pw_9],
+ %[ff_pw_4])
+
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x40)
+ MMI_LDC1(%[ftmp3], %[src], 0x20)
+ MMI_LDC1(%[ftmp4], %[src], 0x60)
+
+ VC1_INV_TRANCS_8_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ff_pw_12], %[ff_pw_16], %[ff_pw_6],
+ %[ff_pw_4])
+
+
+ PSRAH_8_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp4], %[ftmp3], %[ftmp2], %[ftmp1], %[ftmp0])
+
+ TRANSPOSE_4H(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ MMI_SDC1(%[ftmp5], %[dst], 0x00)
+ MMI_SDC1(%[ftmp6], %[dst], 0x10)
+ MMI_SDC1(%[ftmp7], %[dst], 0x20)
+ MMI_SDC1(%[ftmp8], %[dst], 0x30)
+
+ TRANSPOSE_4H(%[ftmp4], %[ftmp3], %[ftmp2], %[ftmp1],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ MMI_SDC1(%[ftmp4], %[dst], 0x08)
+ MMI_SDC1(%[ftmp3], %[dst], 0x18)
+ MMI_SDC1(%[ftmp2], %[dst], 0x28)
+ MMI_SDC1(%[ftmp1], %[dst], 0x38)
+
+ "addiu %[count], %[count], -0x01 \n\t"
+ PTR_ADDIU "%[src], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst], %[dst], 0x40 \n\t"
+ "bnez %[count], 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]),
+ [ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]),
+ [ftmp14]"=&f"(ftmp[14]), [ftmp15]"=&f"(ftmp[15]),
+ [tmp0]"=&r"(tmp[0]),
+ [count]"=&r"(count),
+ [src]"+&r"(src), [dst]"+&r"(dst)
+ : [ff_pw_4]"f"(ff_pw_4), [ff_pw_6]"f"(ff_pw_6),
+ [ff_pw_9]"f"(ff_pw_9), [ff_pw_12]"f"(ff_pw_12),
+ [ff_pw_15]"f"(ff_pw_15), [ff_pw_16]"f"(ff_pw_16)
+ : "memory"
+ );
+
+ src = temp;
+ dst = block;
+
+ // 2nd loop
+ __asm__ volatile (
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+ "li %[count], 0x02 \n\t"
+
+ "1: \n\t"
+ MMI_LDC1(%[ftmp5], %[src], 0x10)
+ MMI_LDC1(%[ftmp6], %[src], 0x30)
+ MMI_LDC1(%[ftmp7], %[src], 0x50)
+ MMI_LDC1(%[ftmp8], %[src], 0x70)
+
+ VC1_INV_TRANCS_8_STEP1_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ff_pw_16], %[ff_pw_15], %[ff_pw_9],
+ %[ff_pw_4])
+
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x40)
+ MMI_LDC1(%[ftmp3], %[src], 0x20)
+ MMI_LDC1(%[ftmp4], %[src], 0x60)
+
+ VC1_INV_TRANCS_8_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ff_pw_12], %[ff_pw_16], %[ff_pw_6],
+ %[ff_pw_64])
+
+ "paddh %[ftmp4], %[ftmp4], %[ff_pw_1] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ff_pw_1] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ff_pw_1] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ff_pw_1] \n\t"
+
+ PSRAH_8_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp4], %[ftmp3], %[ftmp2], %[ftmp1], %[ftmp0])
+
+ MMI_SDC1(%[ftmp5], %[dst], 0x00)
+ MMI_SDC1(%[ftmp6], %[dst], 0x10)
+ MMI_SDC1(%[ftmp7], %[dst], 0x20)
+ MMI_SDC1(%[ftmp8], %[dst], 0x30)
+
+ MMI_SDC1(%[ftmp4], %[dst], 0x40)
+ MMI_SDC1(%[ftmp3], %[dst], 0x50)
+ MMI_SDC1(%[ftmp2], %[dst], 0x60)
+ MMI_SDC1(%[ftmp1], %[dst], 0x70)
+
+ "addiu %[count], %[count], -0x01 \n\t"
+ PTR_ADDIU "%[src], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst], %[dst], 0x08 \n\t"
+ "bnez %[count], 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]),
+ [ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]),
+ [ftmp14]"=&f"(ftmp[14]), [ftmp15]"=&f"(ftmp[15]),
+ [tmp0]"=&r"(tmp[0]),
+ [count]"=&r"(count),
+ [src]"+&r"(src), [dst]"+&r"(dst)
+ : [ff_pw_1]"f"(ff_pw_1), [ff_pw_4]"f"(ff_pw_4),
+ [ff_pw_6]"f"(ff_pw_6), [ff_pw_9]"f"(ff_pw_9),
+ [ff_pw_12]"f"(ff_pw_12), [ff_pw_15]"f"(ff_pw_15),
+ [ff_pw_16]"f"(ff_pw_16), [ff_pw_64]"f"(ff_pw_64)
+ : "memory"
+ );
+}
+#endif
+
+/* Do inverse transform on 8x4 part of block */
+void ff_vc1_inv_trans_8x4_dc_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int dc = block[0];
+ double ftmp[9];
+
+ dc = ( 3 * dc + 1) >> 1;
+ dc = (17 * dc + 64) >> 7;
+
+ __asm__ volatile(
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "pshufh %[dc], %[dc], %[ftmp0] \n\t"
+
+ MMI_LDC1(%[ftmp1], %[dest0], 0x00)
+ MMI_LDC1(%[ftmp2], %[dest1], 0x00)
+ MMI_LDC1(%[ftmp3], %[dest2], 0x00)
+ MMI_LDC1(%[ftmp4], %[dest3], 0x00)
+
+ "punpckhbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp7], %[ftmp3], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+
+ "paddsh %[ftmp1], %[ftmp1], %[dc] \n\t"
+ "paddsh %[ftmp2], %[ftmp2], %[dc] \n\t"
+ "paddsh %[ftmp3], %[ftmp3], %[dc] \n\t"
+ "paddsh %[ftmp4], %[ftmp4], %[dc] \n\t"
+ "paddsh %[ftmp5], %[ftmp5], %[dc] \n\t"
+ "paddsh %[ftmp6], %[ftmp6], %[dc] \n\t"
+ "paddsh %[ftmp7], %[ftmp7], %[dc] \n\t"
+ "paddsh %[ftmp8], %[ftmp8], %[dc] \n\t"
+
+ "packushb %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
+
+ MMI_SDC1(%[ftmp1], %[dest0], 0x00)
+ MMI_SDC1(%[ftmp2], %[dest1], 0x00)
+ MMI_SDC1(%[ftmp3], %[dest2], 0x00)
+ MMI_SDC1(%[ftmp4], %[dest3], 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])
+ : [dest0]"r"(dest+0*linesize), [dest1]"r"(dest+1*linesize),
+ [dest2]"r"(dest+2*linesize), [dest3]"r"(dest+3*linesize),
+ [dc]"f"(dc)
+ : "memory"
+ );
+}
+
+#if _MIPS_SIM != _ABIO32
+void ff_vc1_inv_trans_8x4_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int16_t *src = block;
+ int16_t *dst = block;
+ double ftmp[16];
+ uint32_t tmp[1];
+ mips_reg addr[1];
+ DECLARE_VAR_LOW32;
+
+ // 1st loop
+ __asm__ volatile (
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x08)
+ MMI_LDC1(%[ftmp3], %[src], 0x10)
+ MMI_LDC1(%[ftmp4], %[src], 0x18)
+ MMI_LDC1(%[ftmp5], %[src], 0x20)
+ MMI_LDC1(%[ftmp6], %[src], 0x28)
+ MMI_LDC1(%[ftmp7], %[src], 0x30)
+ MMI_LDC1(%[ftmp8], %[src], 0x38)
+
+ // a1 b1 a3 b2
+ TRANSPOSE_4H(%[ftmp1], %[ftmp3], %[ftmp5], %[ftmp7],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ // a2 b3 a4 b4
+ TRANSPOSE_4H(%[ftmp2], %[ftmp4], %[ftmp6], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ // input b1 b2 b3 b4
+ VC1_INV_TRANCS_8_STEP1_MMI(%[ftmp3], %[ftmp7], %[ftmp4], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp0], %[ftmp13], %[ftmp14], %[ftmp15],
+ %[ff_pw_16], %[ff_pw_15], %[ff_pw_9],
+ %[ff_pw_4])
+ // input a1 a2 a3 a4
+ VC1_INV_TRANCS_8_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp5], %[ftmp6],
+ %[ftmp3], %[ftmp7], %[ftmp4], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ff_pw_12], %[ff_pw_16], %[ff_pw_6],
+ %[ff_pw_4])
+
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+
+ PSRAH_8_MMI(%[ftmp3], %[ftmp7], %[ftmp4], %[ftmp8],
+ %[ftmp6], %[ftmp5], %[ftmp2], %[ftmp1], %[ftmp0])
+
+ TRANSPOSE_4H(%[ftmp3], %[ftmp7], %[ftmp4], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ MMI_SDC1(%[ftmp3], %[dst], 0x00)
+ MMI_SDC1(%[ftmp7], %[dst], 0x10)
+ MMI_SDC1(%[ftmp4], %[dst], 0x20)
+ MMI_SDC1(%[ftmp8], %[dst], 0x30)
+
+ TRANSPOSE_4H(%[ftmp6], %[ftmp5], %[ftmp2], %[ftmp1],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp13], %[tmp0], %[ftmp14], %[ftmp15])
+
+ MMI_SDC1(%[ftmp6], %[dst], 0x08)
+ MMI_SDC1(%[ftmp5], %[dst], 0x18)
+ MMI_SDC1(%[ftmp2], %[dst], 0x28)
+ MMI_SDC1(%[ftmp1], %[dst], 0x38)
+ : [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]),
+ [ftmp14]"=&f"(ftmp[14]), [ftmp15]"=&f"(ftmp[15]),
+ [tmp0]"=&r"(tmp[0])
+ : [src]"r"(src), [dst]"r"(dst),
+ [ff_pw_4]"f"(ff_pw_4), [ff_pw_6]"f"(ff_pw_6),
+ [ff_pw_9]"f"(ff_pw_9), [ff_pw_12]"f"(ff_pw_12),
+ [ff_pw_15]"f"(ff_pw_15), [ff_pw_16]"f"(ff_pw_16)
+ : "memory"
+ );
+
+ src = block;
+
+ // 2nd loop
+ __asm__ volatile (
+ "li %[tmp0], 0x07 \n\t"
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[tmp0], %[ftmp9] \n\t"
+
+ // dest low 32bit
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x20)
+ MMI_LDC1(%[ftmp3], %[src], 0x30)
+ MMI_LDC1(%[ftmp4], %[src], 0x10)
+
+ VC1_INV_TRANCS_4_STEP1_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ff_pw_17], %[ff_pw_10], %[ff_pw_22],
+ %[ff_pw_64])
+
+ PSRAH_4_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4], %[ftmp9])
+
+ MMI_LWC1(%[ftmp5], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp6], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp7], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp8], %[addr0], 0x00)
+
+ VC1_INV_TRANCS_4_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp0])
+
+ MMI_SWC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp2], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp3], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp4], %[addr0], 0x00)
+
+ // dest high 32bit
+ MMI_LDC1(%[ftmp1], %[src], 0x08)
+ MMI_LDC1(%[ftmp2], %[src], 0x28)
+ MMI_LDC1(%[ftmp3], %[src], 0x38)
+ MMI_LDC1(%[ftmp4], %[src], 0x18)
+
+ VC1_INV_TRANCS_4_STEP1_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ff_pw_17], %[ff_pw_10], %[ff_pw_22],
+ %[ff_pw_64])
+
+ PSRAH_4_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4], %[ftmp9])
+
+ MMI_LWC1(%[ftmp5], %[dest], 0x04)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp6], %[addr0], 0x04)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp7], %[addr0], 0x04)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp8], %[addr0], 0x04)
+
+ VC1_INV_TRANCS_4_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp0])
+
+ MMI_SWC1(%[ftmp1], %[dest], 0x04)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp2], %[addr0], 0x04)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp3], %[addr0], 0x04)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp4], %[addr0], 0x04)
+
+ : [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_LOW32
+ [addr0]"=&r"(addr[0])
+ : [src]"r"(src), [dest]"r"(dest),
+ [linesize]"r"((mips_reg)linesize),
+ [ff_pw_17]"f"(ff_pw_17), [ff_pw_22]"f"(ff_pw_22),
+ [ff_pw_10]"f"(ff_pw_10), [ff_pw_64]"f"(ff_pw_64)
+ : "memory"
+ );
+}
+#endif
+
+/* Do inverse transform on 4x8 parts of block */
+void ff_vc1_inv_trans_4x8_dc_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int dc = block[0];
+ double ftmp[9];
+ DECLARE_VAR_LOW32;
+
+ dc = (17 * dc + 4) >> 3;
+ dc = (12 * dc + 64) >> 7;
+
+ __asm__ volatile(
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "pshufh %[dc], %[dc], %[ftmp0] \n\t"
+
+ MMI_LWC1(%[ftmp1], %[dest0], 0x00)
+ MMI_LWC1(%[ftmp2], %[dest1], 0x00)
+ MMI_LWC1(%[ftmp3], %[dest2], 0x00)
+ MMI_LWC1(%[ftmp4], %[dest3], 0x00)
+ MMI_LWC1(%[ftmp5], %[dest4], 0x00)
+ MMI_LWC1(%[ftmp6], %[dest5], 0x00)
+ MMI_LWC1(%[ftmp7], %[dest6], 0x00)
+ MMI_LWC1(%[ftmp8], %[dest7], 0x00)
+
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t"
+
+ "paddsh %[ftmp1], %[ftmp1], %[dc] \n\t"
+ "paddsh %[ftmp2], %[ftmp2], %[dc] \n\t"
+ "paddsh %[ftmp3], %[ftmp3], %[dc] \n\t"
+ "paddsh %[ftmp4], %[ftmp4], %[dc] \n\t"
+ "paddsh %[ftmp5], %[ftmp5], %[dc] \n\t"
+ "paddsh %[ftmp6], %[ftmp6], %[dc] \n\t"
+ "paddsh %[ftmp7], %[ftmp7], %[dc] \n\t"
+ "paddsh %[ftmp8], %[ftmp8], %[dc] \n\t"
+
+ "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+ "packushb %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
+ "packushb %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
+ "packushb %[ftmp7], %[ftmp7], %[ftmp0] \n\t"
+ "packushb %[ftmp8], %[ftmp8], %[ftmp0] \n\t"
+
+ MMI_SWC1(%[ftmp1], %[dest0], 0x00)
+ MMI_SWC1(%[ftmp2], %[dest1], 0x00)
+ MMI_SWC1(%[ftmp3], %[dest2], 0x00)
+ MMI_SWC1(%[ftmp4], %[dest3], 0x00)
+ MMI_SWC1(%[ftmp5], %[dest4], 0x00)
+ MMI_SWC1(%[ftmp6], %[dest5], 0x00)
+ MMI_SWC1(%[ftmp7], %[dest6], 0x00)
+ MMI_SWC1(%[ftmp8], %[dest7], 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]),
+ RESTRICT_ASM_LOW32
+ [ftmp8]"=&f"(ftmp[8])
+ : [dest0]"r"(dest+0*linesize), [dest1]"r"(dest+1*linesize),
+ [dest2]"r"(dest+2*linesize), [dest3]"r"(dest+3*linesize),
+ [dest4]"r"(dest+4*linesize), [dest5]"r"(dest+5*linesize),
+ [dest6]"r"(dest+6*linesize), [dest7]"r"(dest+7*linesize),
+ [dc]"f"(dc)
+ : "memory"
+ );
+}
+
+#if _MIPS_SIM != _ABIO32
+void ff_vc1_inv_trans_4x8_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int16_t *src = block;
+ int16_t *dst = block;
+ double ftmp[16];
+ uint32_t count, tmp[1];
+ mips_reg addr[1];
+ DECLARE_VAR_LOW32;
+
+ // 1st loop
+ __asm__ volatile (
+ "li %[count], 0x02 \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x10)
+ MMI_LDC1(%[ftmp3], %[src], 0x20)
+ MMI_LDC1(%[ftmp4], %[src], 0x30)
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp10], %[ftmp11])
+
+ // t1 t2 t3 t4
+ VC1_INV_TRANCS_4_STEP1_MMI(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ff_pw_17], %[ff_pw_10], %[ff_pw_22],
+ %[ff_pw_4])
+
+ PSRAH_4_MMI(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2], %[ftmp0])
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp10], %[ftmp11])
+
+ MMI_SDC1(%[ftmp1], %[dst], 0x00)
+ MMI_SDC1(%[ftmp3], %[dst], 0x10)
+ MMI_SDC1(%[ftmp4], %[dst], 0x20)
+ MMI_SDC1(%[ftmp2], %[dst], 0x30)
+
+ "addiu %[count], %[count], -0x01 \n\t"
+ PTR_ADDIU "%[src], %[src], 0x40 \n\t"
+ PTR_ADDIU "%[dst], %[dst], 0x40 \n\t"
+ "bnez %[count], 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]),
+ [count]"=&r"(count),
+ [src]"+&r"(src), [dst]"+&r"(dst)
+ : [ff_pw_17]"f"(ff_pw_17), [ff_pw_10]"f"(ff_pw_10),
+ [ff_pw_22]"f"(ff_pw_22), [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+
+ src = block;
+
+ // 2nd loop
+ __asm__ volatile (
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+
+ MMI_LDC1(%[ftmp5], %[src], 0x10)
+ MMI_LDC1(%[ftmp6], %[src], 0x30)
+ MMI_LDC1(%[ftmp7], %[src], 0x50)
+ MMI_LDC1(%[ftmp8], %[src], 0x70)
+
+ VC1_INV_TRANCS_8_STEP1_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ff_pw_16], %[ff_pw_15], %[ff_pw_9],
+ %[ff_pw_4])
+
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x40)
+ MMI_LDC1(%[ftmp3], %[src], 0x20)
+ MMI_LDC1(%[ftmp4], %[src], 0x60)
+
+ VC1_INV_TRANCS_8_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ff_pw_12], %[ff_pw_16], %[ff_pw_6],
+ %[ff_pw_64])
+
+ "paddh %[ftmp4], %[ftmp4], %[ff_pw_1] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ff_pw_1] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ff_pw_1] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ff_pw_1] \n\t"
+
+ PSRAH_8_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp4], %[ftmp3], %[ftmp2], %[ftmp1], %[ftmp0])
+
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+
+ // dest low
+ MMI_LWC1(%[ftmp9], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp10], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp11], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp12], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+
+ VC1_INV_TRANCS_4_STEP2_MMI(%[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp0])
+
+ // dest high
+ MMI_LWC1(%[ftmp9], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp10], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp11], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp12], %[addr0], 0x00)
+
+ VC1_INV_TRANCS_4_STEP2_MMI(%[ftmp4], %[ftmp3], %[ftmp2], %[ftmp1],
+ %[ftmp9], %[ftmp10], %[ftmp11], %[ftmp12],
+ %[ftmp0])
+
+ // dest low
+ MMI_SWC1(%[ftmp5], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp6], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp7], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp8], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+
+ // dest high
+ MMI_SWC1(%[ftmp4], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp3], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp2], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp1], %[addr0], 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]),
+ [ftmp12]"=&f"(ftmp[12]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_LOW32
+ [addr0]"=&r"(addr[0]),
+ [dest]"+&r"(dest)
+ : [src]"r"(src), [linesize]"r"(linesize),
+ [ff_pw_1]"f"(ff_pw_1), [ff_pw_4]"f"(ff_pw_4),
+ [ff_pw_6]"f"(ff_pw_6), [ff_pw_9]"f"(ff_pw_9),
+ [ff_pw_12]"f"(ff_pw_12), [ff_pw_15]"f"(ff_pw_15),
+ [ff_pw_16]"f"(ff_pw_16), [ff_pw_64]"f"(ff_pw_64)
+ : "memory"
+ );
+}
+#endif
+
+/* Do inverse transform on 4x4 part of block */
+void ff_vc1_inv_trans_4x4_dc_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int dc = block[0];
+ double ftmp[5];
+ DECLARE_VAR_LOW32;
+
+ dc = (17 * dc + 4) >> 3;
+ dc = (17 * dc + 64) >> 7;
+
+ __asm__ volatile(
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "pshufh %[dc], %[dc], %[ftmp0] \n\t"
+
+ MMI_LWC1(%[ftmp1], %[dest0], 0x00)
+ MMI_LWC1(%[ftmp2], %[dest1], 0x00)
+ MMI_LWC1(%[ftmp3], %[dest2], 0x00)
+ MMI_LWC1(%[ftmp4], %[dest3], 0x00)
+
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+
+ "paddsh %[ftmp1], %[ftmp1], %[dc] \n\t"
+ "paddsh %[ftmp2], %[ftmp2], %[dc] \n\t"
+ "paddsh %[ftmp3], %[ftmp3], %[dc] \n\t"
+ "paddsh %[ftmp4], %[ftmp4], %[dc] \n\t"
+
+ "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+
+ MMI_SWC1(%[ftmp1], %[dest0], 0x00)
+ MMI_SWC1(%[ftmp2], %[dest1], 0x00)
+ MMI_SWC1(%[ftmp3], %[dest2], 0x00)
+ MMI_SWC1(%[ftmp4], %[dest3], 0x00)
+ : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
+ [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
+ RESTRICT_ASM_LOW32
+ [ftmp4]"=&f"(ftmp[4])
+ : [dest0]"r"(dest+0*linesize), [dest1]"r"(dest+1*linesize),
+ [dest2]"r"(dest+2*linesize), [dest3]"r"(dest+3*linesize),
+ [dc]"f"(dc)
+ : "memory"
+ );
+}
+
+void ff_vc1_inv_trans_4x4_mmi(uint8_t *dest, int linesize, int16_t *block)
+{
+ int16_t *src = block;
+ int16_t *dst = block;
+ double ftmp[12];
+ uint32_t tmp[1];
+ mips_reg addr[1];
+ DECLARE_VAR_LOW32;
+
+ // 1st loop
+ __asm__ volatile (
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x10)
+ MMI_LDC1(%[ftmp3], %[src], 0x20)
+ MMI_LDC1(%[ftmp4], %[src], 0x30)
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp10], %[ftmp11])
+
+ // t1 t2 t3 t4
+ VC1_INV_TRANCS_4_STEP1_MMI(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ff_pw_17], %[ff_pw_10], %[ff_pw_22],
+ %[ff_pw_4])
+
+ PSRAH_4_MMI(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2], %[ftmp0])
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp3], %[ftmp4], %[ftmp2],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp10], %[ftmp11])
+
+ MMI_SDC1(%[ftmp1], %[dst], 0x00)
+ MMI_SDC1(%[ftmp3], %[dst], 0x10)
+ MMI_SDC1(%[ftmp4], %[dst], 0x20)
+ MMI_SDC1(%[ftmp2], %[dst], 0x30)
+ : [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]),
+ [src]"+&r"(src), [dst]"+&r"(dst)
+ : [ff_pw_17]"f"(ff_pw_17), [ff_pw_10]"f"(ff_pw_10),
+ [ff_pw_22]"f"(ff_pw_22), [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+
+ src = block;
+
+ // 2nd loop
+ __asm__ volatile (
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp0] \n\t"
+
+ // dest low 32bit
+ MMI_LDC1(%[ftmp1], %[src], 0x00)
+ MMI_LDC1(%[ftmp2], %[src], 0x20)
+ MMI_LDC1(%[ftmp3], %[src], 0x30)
+ MMI_LDC1(%[ftmp4], %[src], 0x10)
+
+ VC1_INV_TRANCS_4_STEP1_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ff_pw_17], %[ff_pw_10], %[ff_pw_22],
+ %[ff_pw_64])
+
+ PSRAH_4_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4], %[ftmp0])
+
+ MMI_LWC1(%[ftmp5], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp6], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp7], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_LWC1(%[ftmp8], %[addr0], 0x00)
+
+ "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t"
+
+ VC1_INV_TRANCS_4_STEP2_MMI(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9])
+
+ MMI_SWC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[addr0], %[dest], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp2], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp3], %[addr0], 0x00)
+ PTR_ADDU "%[addr0], %[addr0], %[linesize] \n\t"
+ MMI_SWC1(%[ftmp4], %[addr0], 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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_LOW32
+ [addr0]"=&r"(addr[0])
+ : [src]"r"(src), [dest]"r"(dest),
+ [linesize]"r"((mips_reg)linesize),
+ [ff_pw_17]"f"(ff_pw_17), [ff_pw_22]"f"(ff_pw_22),
+ [ff_pw_10]"f"(ff_pw_10), [ff_pw_64]"f"(ff_pw_64)
+ : "memory"
+ );
+}
+
+/* Apply overlap transform to horizontal edge */
+void ff_vc1_h_overlap_mmi(uint8_t *src, int stride)
+{
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd = 1;
+ for (i = 0; i < 8; i++) {
+ a = src[-2];
+ b = src[-1];
+ c = src[0];
+ d = src[1];
+ d1 = (a - d + 3 + rnd) >> 3;
+ d2 = (a - d + b - c + 4 - rnd) >> 3;
+
+ src[-2] = a - d1;
+ src[-1] = av_clip_uint8(b - d2);
+ src[0] = av_clip_uint8(c + d2);
+ src[1] = d + d1;
+ src += stride;
+ rnd = !rnd;
+ }
+}
+
+void ff_vc1_h_s_overlap_mmi(int16_t *left, int16_t *right)
+{
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd1 = 4, rnd2 = 3;
+ for (i = 0; i < 8; i++) {
+ a = left[6];
+ b = left[7];
+ c = right[0];
+ d = right[1];
+ d1 = a - d;
+ d2 = a - d + b - c;
+
+ left[6] = ((a << 3) - d1 + rnd1) >> 3;
+ left[7] = ((b << 3) - d2 + rnd2) >> 3;
+ right[0] = ((c << 3) + d2 + rnd1) >> 3;
+ right[1] = ((d << 3) + d1 + rnd2) >> 3;
+
+ right += 8;
+ left += 8;
+ rnd2 = 7 - rnd2;
+ rnd1 = 7 - rnd1;
+ }
+}
+
+/* Apply overlap transform to vertical edge */
+void ff_vc1_v_overlap_mmi(uint8_t *src, int stride)
+{
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd = 1;
+ for (i = 0; i < 8; i++) {
+ a = src[-2 * stride];
+ b = src[-stride];
+ c = src[0];
+ d = src[stride];
+ d1 = (a - d + 3 + rnd) >> 3;
+ d2 = (a - d + b - c + 4 - rnd) >> 3;
+
+ src[-2 * stride] = a - d1;
+ src[-stride] = av_clip_uint8(b - d2);
+ src[0] = av_clip_uint8(c + d2);
+ src[stride] = d + d1;
+ src++;
+ rnd = !rnd;
+ }
+}
+
+void ff_vc1_v_s_overlap_mmi(int16_t *top, int16_t *bottom)
+{
+ int i;
+ int a, b, c, d;
+ int d1, d2;
+ int rnd1 = 4, rnd2 = 3;
+ for (i = 0; i < 8; i++) {
+ a = top[48];
+ b = top[56];
+ c = bottom[0];
+ d = bottom[8];
+ d1 = a - d;
+ d2 = a - d + b - c;
+
+ top[48] = ((a << 3) - d1 + rnd1) >> 3;
+ top[56] = ((b << 3) - d2 + rnd2) >> 3;
+ bottom[0] = ((c << 3) + d2 + rnd1) >> 3;
+ bottom[8] = ((d << 3) + d1 + rnd2) >> 3;
+
+ bottom++;
+ top++;
+ rnd2 = 7 - rnd2;
+ rnd1 = 7 - rnd1;
+ }
+}
+
+/**
+ * VC-1 in-loop deblocking filter for one line
+ * @param src source block type
+ * @param stride block stride
+ * @param pq block quantizer
+ * @return whether other 3 pairs should be filtered or not
+ * @see 8.6
+ */
+static av_always_inline int vc1_filter_line(uint8_t *src, int stride, int pq)
+{
+ int a0 = (2 * (src[-2 * stride] - src[1 * stride]) -
+ 5 * (src[-1 * stride] - src[0 * stride]) + 4) >> 3;
+ int a0_sign = a0 >> 31; /* Store sign */
+
+ a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */
+ if (a0 < pq) {
+ int a1 = FFABS((2 * (src[-4 * stride] - src[-1 * stride]) -
+ 5 * (src[-3 * stride] - src[-2 * stride]) + 4) >> 3);
+ int a2 = FFABS((2 * (src[ 0 * stride] - src[ 3 * stride]) -
+ 5 * (src[ 1 * stride] - src[ 2 * stride]) + 4) >> 3);
+ if (a1 < a0 || a2 < a0) {
+ int clip = src[-1 * stride] - src[0 * stride];
+ int clip_sign = clip >> 31;
+
+ clip = ((clip ^ clip_sign) - clip_sign) >> 1;
+ if (clip) {
+ int a3 = FFMIN(a1, a2);
+ int d = 5 * (a3 - a0);
+ int d_sign = (d >> 31);
+
+ d = ((d ^ d_sign) - d_sign) >> 3;
+ d_sign ^= a0_sign;
+
+ if (d_sign ^ clip_sign)
+ d = 0;
+ else {
+ d = FFMIN(d, clip);
+ d = (d ^ d_sign) - d_sign; /* Restore sign */
+ src[-1 * stride] = av_clip_uint8(src[-1 * stride] - d);
+ src[ 0 * stride] = av_clip_uint8(src[ 0 * stride] + d);
+ }
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * VC-1 in-loop deblocking filter
+ * @param src source block type
+ * @param step distance between horizontally adjacent elements
+ * @param stride distance between vertically adjacent elements
+ * @param len edge length to filter (4 or 8 pixels)
+ * @param pq block quantizer
+ * @see 8.6
+ */
+static inline void vc1_loop_filter(uint8_t *src, int step, int stride,
+ int len, int pq)
+{
+ int i;
+ int filt3;
+
+ for (i = 0; i < len; i += 4) {
+ filt3 = vc1_filter_line(src + 2 * step, stride, pq);
+ if (filt3) {
+ vc1_filter_line(src + 0 * step, stride, pq);
+ vc1_filter_line(src + 1 * step, stride, pq);
+ vc1_filter_line(src + 3 * step, stride, pq);
+ }
+ src += step * 4;
+ }
+}
+
+void ff_vc1_v_loop_filter4_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, 1, stride, 4, pq);
+}
+
+void ff_vc1_h_loop_filter4_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, stride, 1, 4, pq);
+}
+
+void ff_vc1_v_loop_filter8_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, 1, stride, 8, pq);
+}
+
+void ff_vc1_h_loop_filter8_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, stride, 1, 8, pq);
+}
+
+void ff_vc1_v_loop_filter16_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, 1, stride, 16, pq);
+}
+
+void ff_vc1_h_loop_filter16_mmi(uint8_t *src, int stride, int pq)
+{
+ vc1_loop_filter(src, stride, 1, 16, pq);
+}
+
+void ff_put_vc1_mspel_mc00_mmi(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t stride, int rnd)
+{
+ ff_put_pixels8_8_mmi(dst, src, stride, 8);
+}
+void ff_put_vc1_mspel_mc00_16_mmi(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t stride, int rnd)
+{
+ ff_put_pixels16_8_mmi(dst, src, stride, 16);
+}
+void ff_avg_vc1_mspel_mc00_mmi(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t stride, int rnd)
+{
+ ff_avg_pixels8_8_mmi(dst, src, stride, 8);
+}
+void ff_avg_vc1_mspel_mc00_16_mmi(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t stride, int rnd)
+{
+ ff_avg_pixels16_8_mmi(dst, src, stride, 16);
+}
+
+#define OP_PUT(S, D)
+#define OP_AVG(S, D) \
+ "ldc1 $f16, "#S" \n\t" \
+ "pavgb "#D", "#D", $f16 \n\t"
+
+/** Add rounder from $f14 to $f6 and pack result at destination */
+#define NORMALIZE_MMI(SHIFT) \
+ "paddh $f6, $f6, $f14 \n\t" /* +bias-r */ \
+ "paddh $f8, $f8, $f14 \n\t" /* +bias-r */ \
+ "psrah $f6, $f6, "SHIFT" \n\t" \
+ "psrah $f8, $f8, "SHIFT" \n\t"
+
+#define TRANSFER_DO_PACK(OP) \
+ "packushb $f6, $f6, $f8 \n\t" \
+ OP((%[dst]), $f6) \
+ "sdc1 $f6, 0x00(%[dst]) \n\t"
+
+#define TRANSFER_DONT_PACK(OP) \
+ OP(0(%[dst]), $f6) \
+ OP(8(%[dst]), $f8) \
+ "sdc1 $f6, 0x00(%[dst]) \n\t" \
+ "sdc1 $f8, 0x08(%[dst]) \n\t"
+
+/** @see MSPEL_FILTER13_CORE for use as UNPACK macro */
+#define DO_UNPACK(reg) \
+ "punpcklbh "reg", "reg", $f0 \n\t"
+#define DONT_UNPACK(reg)
+
+/** Compute the rounder 32-r or 8-r and unpacks it to $f14 */
+#define LOAD_ROUNDER_MMI(ROUND) \
+ "lwc1 $f14, "ROUND" \n\t" \
+ "punpcklhw $f14, $f14, $f14 \n\t" \
+ "punpcklwd $f14, $f14, $f14 \n\t"
+
+
+#define SHIFT2_LINE(OFF, R0, R1, R2, R3) \
+ "paddh "#R1", "#R1", "#R2" \n\t" \
+ PTR_ADDU "$9, %[src], %[stride1] \n\t" \
+ MMI_ULWC1(R0, $9, 0x00) \
+ "pmullh "#R1", "#R1", $f6 \n\t" \
+ "punpcklbh "#R0", "#R0", $f0 \n\t" \
+ PTR_ADDU "$9, %[src], %[stride] \n\t" \
+ MMI_ULWC1(R3, $9, 0x00) \
+ "psubh "#R1", "#R1", "#R0" \n\t" \
+ "punpcklbh "#R3", "#R3", $f0 \n\t" \
+ "paddh "#R1", "#R1", $f14 \n\t" \
+ "psubh "#R1", "#R1", "#R3" \n\t" \
+ "psrah "#R1", "#R1", %[shift] \n\t" \
+ MMI_SDC1(R1, %[dst], OFF) \
+ PTR_ADDU "%[src], %[src], %[stride] \n\t"
+
+/** Sacrificing $f12 makes it possible to pipeline loads from src */
+static void vc1_put_ver_16b_shift2_mmi(int16_t *dst,
+ const uint8_t *src, mips_reg stride,
+ int rnd, int64_t shift)
+{
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ADDRT;
+
+ __asm__ volatile(
+ "xor $f0, $f0, $f0 \n\t"
+ "li $8, 0x03 \n\t"
+ LOAD_ROUNDER_MMI("%[rnd]")
+ "ldc1 $f12, %[ff_pw_9] \n\t"
+ "1: \n\t"
+ MMI_ULWC1($f4, %[src], 0x00)
+ PTR_ADDU "%[src], %[src], %[stride] \n\t"
+ MMI_ULWC1($f6, %[src], 0x00)
+ "punpcklbh $f4, $f4, $f0 \n\t"
+ "punpcklbh $f6, $f6, $f0 \n\t"
+ SHIFT2_LINE( 0, $f2, $f4, $f6, $f8)
+ SHIFT2_LINE( 24, $f4, $f6, $f8, $f2)
+ SHIFT2_LINE( 48, $f6, $f8, $f2, $f4)
+ SHIFT2_LINE( 72, $f8, $f2, $f4, $f6)
+ SHIFT2_LINE( 96, $f2, $f4, $f6, $f8)
+ SHIFT2_LINE(120, $f4, $f6, $f8, $f2)
+ SHIFT2_LINE(144, $f6, $f8, $f2, $f4)
+ SHIFT2_LINE(168, $f8, $f2, $f4, $f6)
+ PTR_SUBU "%[src], %[src], %[stride2] \n\t"
+ PTR_ADDIU "%[dst], %[dst], 0x08 \n\t"
+ "addiu $8, $8, -0x01 \n\t"
+ "bnez $8, 1b \n\t"
+ : RESTRICT_ASM_LOW32 RESTRICT_ASM_ADDRT
+ [src]"+r"(src), [dst]"+r"(dst)
+ : [stride]"r"(stride), [stride1]"r"(-2*stride),
+ [shift]"f"(shift), [rnd]"m"(rnd),
+ [stride2]"r"(9*stride-4), [ff_pw_9]"m"(ff_pw_9)
+ : "$8", "$9", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", "$f12",
+ "$f14", "$f16", "memory"
+ );
+}
+
+/**
+ * Data is already unpacked, so some operations can directly be made from
+ * memory.
+ */
+#define VC1_HOR_16B_SHIFT2(OP, OPNAME) \
+static void OPNAME ## vc1_hor_16b_shift2_mmi(uint8_t *dst, mips_reg stride, \
+ const int16_t *src, int rnd) \
+{ \
+ int h = 8; \
+ DECLARE_VAR_ALL64; \
+ DECLARE_VAR_ADDRT; \
+ \
+ src -= 1; \
+ rnd -= (-1+9+9-1)*1024; /* Add -1024 bias */ \
+ \
+ __asm__ volatile( \
+ LOAD_ROUNDER_MMI("%[rnd]") \
+ "ldc1 $f12, %[ff_pw_128] \n\t" \
+ "ldc1 $f10, %[ff_pw_9] \n\t" \
+ "1: \n\t" \
+ MMI_ULDC1($f2, %[src], 0x00) \
+ MMI_ULDC1($f4, %[src], 0x08) \
+ MMI_ULDC1($f6, %[src], 0x02) \
+ MMI_ULDC1($f8, %[src], 0x0a) \
+ MMI_ULDC1($f0, %[src], 0x06) \
+ "paddh $f2, $f2, $f0 \n\t" \
+ MMI_ULDC1($f0, %[src], 0x0e) \
+ "paddh $f4, $f4, $f0 \n\t" \
+ MMI_ULDC1($f0, %[src], 0x04) \
+ "paddh $f6, $f6, $f0 \n\t" \
+ MMI_ULDC1($f0, %[src], 0x0b) \
+ "paddh $f8, $f8, $f0 \n\t" \
+ "pmullh $f6, $f6, $f10 \n\t" \
+ "pmullh $f8, $f8, $f10 \n\t" \
+ "psubh $f6, $f6, $f2 \n\t" \
+ "psubh $f8, $f8, $f4 \n\t" \
+ "li $8, 0x07 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ NORMALIZE_MMI("$f16") \
+ /* Remove bias */ \
+ "paddh $f6, $f6, $f12 \n\t" \
+ "paddh $f8, $f8, $f12 \n\t" \
+ TRANSFER_DO_PACK(OP) \
+ "addiu %[h], %[h], -0x01 \n\t" \
+ PTR_ADDIU "%[src], %[src], 0x18 \n\t" \
+ PTR_ADDU "%[dst], %[dst], %[stride] \n\t" \
+ "bnez %[h], 1b \n\t" \
+ : RESTRICT_ASM_ALL64 RESTRICT_ASM_ADDRT \
+ [h]"+r"(h), \
+ [src]"+r"(src), [dst]"+r"(dst) \
+ : [stride]"r"(stride), [rnd]"m"(rnd), \
+ [ff_pw_9]"m"(ff_pw_9), [ff_pw_128]"m"(ff_pw_128) \
+ : "$8", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", "$f12", "$f14", \
+ "$f16", "memory" \
+ ); \
+}
+
+VC1_HOR_16B_SHIFT2(OP_PUT, put_)
+VC1_HOR_16B_SHIFT2(OP_AVG, avg_)
+
+/**
+ * Purely vertical or horizontal 1/2 shift interpolation.
+ * Sacrify $f12 for *9 factor.
+ */
+#define VC1_SHIFT2(OP, OPNAME)\
+static void OPNAME ## vc1_shift2_mmi(uint8_t *dst, const uint8_t *src, \
+ mips_reg stride, int rnd, \
+ mips_reg offset) \
+{ \
+ DECLARE_VAR_LOW32; \
+ DECLARE_VAR_ADDRT; \
+ \
+ rnd = 8 - rnd; \
+ \
+ __asm__ volatile( \
+ "xor $f0, $f0, $f0 \n\t" \
+ "li $10, 0x08 \n\t" \
+ LOAD_ROUNDER_MMI("%[rnd]") \
+ "ldc1 $f12, %[ff_pw_9] \n\t" \
+ "1: \n\t" \
+ MMI_ULWC1($f6, %[src], 0x00) \
+ MMI_ULWC1($f8, %[src], 0x04) \
+ PTR_ADDU "$9, %[src], %[offset] \n\t" \
+ MMI_ULWC1($f2, $9, 0x00) \
+ MMI_ULWC1($f4, $9, 0x04) \
+ PTR_ADDU "%[src], %[src], %[offset] \n\t" \
+ "punpcklbh $f6, $f6, $f0 \n\t" \
+ "punpcklbh $f8, $f8, $f0 \n\t" \
+ "punpcklbh $f2, $f2, $f0 \n\t" \
+ "punpcklbh $f4, $f4, $f0 \n\t" \
+ "paddh $f6, $f6, $f2 \n\t" \
+ "paddh $f8, $f8, $f4 \n\t" \
+ PTR_ADDU "$9, %[src], %[offset_x2n] \n\t" \
+ MMI_ULWC1($f2, $9, 0x00) \
+ MMI_ULWC1($f4, $9, 0x04) \
+ "pmullh $f6, $f6, $f12 \n\t" /* 0,9,9,0*/ \
+ "pmullh $f8, $f8, $f12 \n\t" /* 0,9,9,0*/ \
+ "punpcklbh $f2, $f2, $f0 \n\t" \
+ "punpcklbh $f4, $f4, $f0 \n\t" \
+ "psubh $f6, $f6, $f2 \n\t" /*-1,9,9,0*/ \
+ "psubh $f8, $f8, $f4 \n\t" /*-1,9,9,0*/ \
+ PTR_ADDU "$9, %[src], %[offset] \n\t" \
+ MMI_ULWC1($f2, $9, 0x00) \
+ MMI_ULWC1($f4, $9, 0x04) \
+ "punpcklbh $f2, $f2, $f0 \n\t" \
+ "punpcklbh $f4, $f4, $f0 \n\t" \
+ "psubh $f6, $f6, $f2 \n\t" /*-1,9,9,-1*/ \
+ "psubh $f8, $f8, $f4 \n\t" /*-1,9,9,-1*/ \
+ "li $8, 0x04 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ NORMALIZE_MMI("$f16") \
+ "packushb $f6, $f6, $f8 \n\t" \
+ OP((%[dst]), $f6) \
+ "sdc1 $f6, 0x00(%[dst]) \n\t" \
+ "addiu $10, $10, -0x01 \n\t" \
+ PTR_ADDU "%[src], %[src], %[stride1] \n\t" \
+ PTR_ADDU "%[dst], %[dst], %[stride] \n\t" \
+ "bnez $10, 1b \n\t" \
+ : RESTRICT_ASM_LOW32 RESTRICT_ASM_ADDRT \
+ [src]"+r"(src), [dst]"+r"(dst) \
+ : [offset]"r"(offset), [offset_x2n]"r"(-2*offset), \
+ [stride]"g"(stride), [rnd]"m"(rnd), \
+ [stride1]"g"(stride-offset), \
+ [ff_pw_9]"m"(ff_pw_9) \
+ : "$8", "$9", "$10", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", \
+ "$f12", "$f14", "$f16", "memory" \
+ ); \
+}
+
+VC1_SHIFT2(OP_PUT, put_)
+VC1_SHIFT2(OP_AVG, avg_)
+
+/**
+ * Core of the 1/4 and 3/4 shift bicubic interpolation.
+ *
+ * @param UNPACK Macro unpacking arguments from 8 to 16bits (can be empty).
+ * @param LOAD "MMI_ULWC1" or "MMI_ULDC1", if data read is already unpacked.
+ * @param M "1" for MMI_ULWC1, "2" for MMI_ULDC1.
+ * @param A1 Stride address of 1st tap (beware of unpacked/packed).
+ * @param A2 Stride address of 2nd tap
+ * @param A3 Stride address of 3rd tap
+ * @param A4 Stride address of 4th tap
+ */
+#define MSPEL_FILTER13_CORE(UNPACK, LOAD, M, A1, A2, A3, A4) \
+ PTR_ADDU "$9, %[src], "#A1" \n\t" \
+ LOAD($f2, $9, M*0) \
+ LOAD($f4, $9, M*4) \
+ UNPACK("$f2") \
+ UNPACK("$f4") \
+ "pmullh $f2, $f2, %[ff_pw_3] \n\t" \
+ "pmullh $f4, $f4, %[ff_pw_3] \n\t" \
+ PTR_ADDU "$9, %[src], "#A2" \n\t" \
+ LOAD($f6, $9, M*0) \
+ LOAD($f8, $9, M*4) \
+ UNPACK("$f6") \
+ UNPACK("$f8") \
+ "pmullh $f6, $f6, $f12 \n\t" /* *18 */ \
+ "pmullh $f8, $f8, $f12 \n\t" /* *18 */ \
+ "psubh $f6, $f6, $f2 \n\t" /* *18, -3 */ \
+ "psubh $f8, $f8, $f4 \n\t" /* *18, -3 */ \
+ PTR_ADDU "$9, %[src], "#A4" \n\t" \
+ LOAD($f2, $9, M*0) \
+ LOAD($f4, $9, M*4) \
+ UNPACK("$f2") \
+ UNPACK("$f4") \
+ "li $8, 0x02 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ "psllh $f2, $f2, $f16 \n\t" /* 4* */ \
+ "psllh $f4, $f4, $f16 \n\t" /* 4* */ \
+ "psubh $f6, $f6, $f2 \n\t" /* -4,18,-3 */ \
+ "psubh $f8, $f8, $f4 \n\t" /* -4,18,-3 */ \
+ PTR_ADDU "$9, %[src], "#A3" \n\t" \
+ LOAD($f2, $9, M*0) \
+ LOAD($f4, $9, M*4) \
+ UNPACK("$f2") \
+ UNPACK("$f4") \
+ "pmullh $f2, $f2, $f10 \n\t" /* *53 */ \
+ "pmullh $f4, $f4, $f10 \n\t" /* *53 */ \
+ "paddh $f6, $f6, $f2 \n\t" /* 4,53,18,-3 */ \
+ "paddh $f8, $f8, $f4 \n\t" /* 4,53,18,-3 */
+
+/**
+ * Macro to build the vertical 16bits version of vc1_put_shift[13].
+ * Here, offset=src_stride. Parameters passed A1 to A4 must use
+ * %3 (src_stride), %4 (2*src_stride) and %5 (3*src_stride).
+ *
+ * @param NAME Either 1 or 3
+ * @see MSPEL_FILTER13_CORE for information on A1->A4
+ */
+#define MSPEL_FILTER13_VER_16B(NAME, A1, A2, A3, A4) \
+static void \
+vc1_put_ver_16b_ ## NAME ## _mmi(int16_t *dst, const uint8_t *src, \
+ mips_reg src_stride, \
+ int rnd, int64_t shift) \
+{ \
+ int h = 8; \
+ DECLARE_VAR_LOW32; \
+ DECLARE_VAR_ADDRT; \
+ \
+ src -= src_stride; \
+ \
+ __asm__ volatile( \
+ "xor $f0, $f0, $f0 \n\t" \
+ LOAD_ROUNDER_MMI("%[rnd]") \
+ "ldc1 $f10, %[ff_pw_53] \n\t" \
+ "ldc1 $f12, %[ff_pw_18] \n\t" \
+ ".p2align 3 \n\t" \
+ "1: \n\t" \
+ MSPEL_FILTER13_CORE(DO_UNPACK, MMI_ULWC1, 1, A1, A2, A3, A4) \
+ NORMALIZE_MMI("%[shift]") \
+ TRANSFER_DONT_PACK(OP_PUT) \
+ /* Last 3 (in fact 4) bytes on the line */ \
+ PTR_ADDU "$9, %[src], "#A1" \n\t" \
+ MMI_ULWC1($f2, $9, 0x08) \
+ DO_UNPACK("$f2") \
+ "mov.d $f6, $f2 \n\t" \
+ "paddh $f2, $f2, $f2 \n\t" \
+ "paddh $f2, $f2, $f6 \n\t" /* 3* */ \
+ PTR_ADDU "$9, %[src], "#A2" \n\t" \
+ MMI_ULWC1($f6, $9, 0x08) \
+ DO_UNPACK("$f6") \
+ "pmullh $f6, $f6, $f12 \n\t" /* *18 */ \
+ "psubh $f6, $f6, $f2 \n\t" /* *18,-3 */ \
+ PTR_ADDU "$9, %[src], "#A3" \n\t" \
+ MMI_ULWC1($f2, $9, 0x08) \
+ DO_UNPACK("$f2") \
+ "pmullh $f2, $f2, $f10 \n\t" /* *53 */ \
+ "paddh $f6, $f6, $f2 \n\t" /* *53,18,-3 */ \
+ PTR_ADDU "$9, %[src], "#A4" \n\t" \
+ MMI_ULWC1($f2, $9, 0x08) \
+ DO_UNPACK("$f2") \
+ "li $8, 0x02 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ "psllh $f2, $f2, $f16 \n\t" /* 4* */ \
+ "psubh $f6, $f6, $f2 \n\t" \
+ "paddh $f6, $f6, $f14 \n\t" \
+ "li $8, 0x06 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ "psrah $f6, $f6, $f16 \n\t" \
+ "sdc1 $f6, 0x10(%[dst]) \n\t" \
+ "addiu %[h], %[h], -0x01 \n\t" \
+ PTR_ADDU "%[src], %[src], %[stride_x1] \n\t" \
+ PTR_ADDIU "%[dst], %[dst], 0x18 \n\t" \
+ "bnez %[h], 1b \n\t" \
+ : RESTRICT_ASM_LOW32 RESTRICT_ASM_ADDRT \
+ [h]"+r"(h), \
+ [src]"+r"(src), [dst]"+r"(dst) \
+ : [stride_x1]"r"(src_stride), [stride_x2]"r"(2*src_stride), \
+ [stride_x3]"r"(3*src_stride), \
+ [rnd]"m"(rnd), [shift]"f"(shift), \
+ [ff_pw_53]"m"(ff_pw_53), [ff_pw_18]"m"(ff_pw_18), \
+ [ff_pw_3]"f"(ff_pw_3) \
+ : "$8", "$9", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", "$f12", \
+ "$f14", "$f16", "memory" \
+ ); \
+}
+
+/**
+ * Macro to build the horizontal 16bits version of vc1_put_shift[13].
+ * Here, offset=16bits, so parameters passed A1 to A4 should be simple.
+ *
+ * @param NAME Either 1 or 3
+ * @see MSPEL_FILTER13_CORE for information on A1->A4
+ */
+#define MSPEL_FILTER13_HOR_16B(NAME, A1, A2, A3, A4, OP, OPNAME) \
+static void \
+OPNAME ## vc1_hor_16b_ ## NAME ## _mmi(uint8_t *dst, mips_reg stride, \
+ const int16_t *src, int rnd) \
+{ \
+ int h = 8; \
+ DECLARE_VAR_ALL64; \
+ DECLARE_VAR_ADDRT; \
+ \
+ src -= 1; \
+ rnd -= (-4+58+13-3)*256; /* Add -256 bias */ \
+ \
+ __asm__ volatile( \
+ "xor $f0, $f0, $f0 \n\t" \
+ LOAD_ROUNDER_MMI("%[rnd]") \
+ "ldc1 $f10, %[ff_pw_53] \n\t" \
+ "ldc1 $f12, %[ff_pw_18] \n\t" \
+ ".p2align 3 \n\t" \
+ "1: \n\t" \
+ MSPEL_FILTER13_CORE(DONT_UNPACK, MMI_ULDC1, 2, A1, A2, A3, A4) \
+ "li $8, 0x07 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ NORMALIZE_MMI("$f16") \
+ /* Remove bias */ \
+ "paddh $f6, $f6, %[ff_pw_128] \n\t" \
+ "paddh $f8, $f8, %[ff_pw_128] \n\t" \
+ TRANSFER_DO_PACK(OP) \
+ "addiu %[h], %[h], -0x01 \n\t" \
+ PTR_ADDU "%[src], %[src], 0x18 \n\t" \
+ PTR_ADDU "%[dst], %[dst], %[stride] \n\t" \
+ "bnez %[h], 1b \n\t" \
+ : RESTRICT_ASM_ALL64 RESTRICT_ASM_ADDRT \
+ [h]"+r"(h), \
+ [src]"+r"(src), [dst]"+r"(dst) \
+ : [stride]"r"(stride), [rnd]"m"(rnd), \
+ [ff_pw_53]"m"(ff_pw_53), [ff_pw_18]"m"(ff_pw_18), \
+ [ff_pw_3]"f"(ff_pw_3), [ff_pw_128]"f"(ff_pw_128) \
+ : "$8", "$9", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", "$f12", \
+ "$f14", "$f16", "memory" \
+ ); \
+}
+
+/**
+ * Macro to build the 8bits, any direction, version of vc1_put_shift[13].
+ * Here, offset=src_stride. Parameters passed A1 to A4 must use
+ * %3 (offset), %4 (2*offset) and %5 (3*offset).
+ *
+ * @param NAME Either 1 or 3
+ * @see MSPEL_FILTER13_CORE for information on A1->A4
+ */
+#define MSPEL_FILTER13_8B(NAME, A1, A2, A3, A4, OP, OPNAME) \
+static void \
+OPNAME ## vc1_## NAME ## _mmi(uint8_t *dst, const uint8_t *src, \
+ mips_reg stride, int rnd, mips_reg offset) \
+{ \
+ int h = 8; \
+ DECLARE_VAR_LOW32; \
+ DECLARE_VAR_ADDRT; \
+ \
+ src -= offset; \
+ rnd = 32-rnd; \
+ \
+ __asm__ volatile ( \
+ "xor $f0, $f0, $f0 \n\t" \
+ LOAD_ROUNDER_MMI("%[rnd]") \
+ "ldc1 $f10, %[ff_pw_53] \n\t" \
+ "ldc1 $f12, %[ff_pw_18] \n\t" \
+ ".p2align 3 \n\t" \
+ "1: \n\t" \
+ MSPEL_FILTER13_CORE(DO_UNPACK, MMI_ULWC1, 1, A1, A2, A3, A4) \
+ "li $8, 0x06 \n\t" \
+ "mtc1 $8, $f16 \n\t" \
+ NORMALIZE_MMI("$f16") \
+ TRANSFER_DO_PACK(OP) \
+ "addiu %[h], %[h], -0x01 \n\t" \
+ PTR_ADDU "%[src], %[src], %[stride] \n\t" \
+ PTR_ADDU "%[dst], %[dst], %[stride] \n\t" \
+ "bnez %[h], 1b \n\t" \
+ : RESTRICT_ASM_LOW32 RESTRICT_ASM_ADDRT \
+ [h]"+r"(h), \
+ [src]"+r"(src), [dst]"+r"(dst) \
+ : [offset_x1]"r"(offset), [offset_x2]"r"(2*offset), \
+ [offset_x3]"r"(3*offset), [stride]"g"(stride), \
+ [rnd]"m"(rnd), \
+ [ff_pw_53]"m"(ff_pw_53), [ff_pw_18]"m"(ff_pw_18), \
+ [ff_pw_3]"f"(ff_pw_3) \
+ : "$8", "$9", "$f0", "$f2", "$f4", "$f6", "$f8", "$f10", "$f12", \
+ "$f14", "$f16", "memory" \
+ ); \
+}
+
+
+/** 1/4 shift bicubic interpolation */
+MSPEL_FILTER13_8B(shift1, %[offset_x3], %[offset_x2], %[offset_x1], $0, OP_PUT, put_)
+MSPEL_FILTER13_8B(shift1, %[offset_x3], %[offset_x2], %[offset_x1], $0, OP_AVG, avg_)
+MSPEL_FILTER13_VER_16B(shift1, %[stride_x3], %[stride_x2], %[stride_x1], $0)
+MSPEL_FILTER13_HOR_16B(shift1, 6, 4, 2, 0, OP_PUT, put_)
+MSPEL_FILTER13_HOR_16B(shift1, 6, 4, 2, 0, OP_AVG, avg_)
+
+/** 3/4 shift bicubic interpolation */
+MSPEL_FILTER13_8B(shift3, $0, %[offset_x1], %[offset_x2], %[offset_x3], OP_PUT, put_)
+MSPEL_FILTER13_8B(shift3, $0, %[offset_x1], %[offset_x2], %[offset_x3], OP_AVG, avg_)
+MSPEL_FILTER13_VER_16B(shift3, $0, %[stride_x1], %[stride_x2], %[stride_x3])
+MSPEL_FILTER13_HOR_16B(shift3, 0, 2, 4, 6, OP_PUT, put_)
+MSPEL_FILTER13_HOR_16B(shift3, 0, 2, 4, 6, OP_AVG, avg_)
+
+typedef void (*vc1_mspel_mc_filter_ver_16bits)
+ (int16_t *dst, const uint8_t *src, mips_reg src_stride, int rnd,
+ int64_t shift);
+typedef void (*vc1_mspel_mc_filter_hor_16bits)
+ (uint8_t *dst, mips_reg dst_stride, const int16_t *src, int rnd);
+typedef void (*vc1_mspel_mc_filter_8bits)
+ (uint8_t *dst, const uint8_t *src, mips_reg stride, int rnd,
+ mips_reg offset);
+
+/**
+ * Interpolate fractional pel values by applying proper vertical then
+ * horizontal filter.
+ *
+ * @param dst Destination buffer for interpolated pels.
+ * @param src Source buffer.
+ * @param stride Stride for both src and dst buffers.
+ * @param hmode Horizontal filter (expressed in quarter pixels shift).
+ * @param hmode Vertical filter.
+ * @param rnd Rounding bias.
+ */
+#define VC1_MSPEL_MC(OP) \
+static void OP ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride,\
+ int hmode, int vmode, int rnd) \
+{ \
+ static const vc1_mspel_mc_filter_ver_16bits vc1_put_shift_ver_16bits[] =\
+ { NULL, vc1_put_ver_16b_shift1_mmi, \
+ vc1_put_ver_16b_shift2_mmi, \
+ vc1_put_ver_16b_shift3_mmi }; \
+ static const vc1_mspel_mc_filter_hor_16bits vc1_put_shift_hor_16bits[] =\
+ { NULL, OP ## vc1_hor_16b_shift1_mmi, \
+ OP ## vc1_hor_16b_shift2_mmi, \
+ OP ## vc1_hor_16b_shift3_mmi }; \
+ static const vc1_mspel_mc_filter_8bits vc1_put_shift_8bits[] = \
+ { NULL, OP ## vc1_shift1_mmi, \
+ OP ## vc1_shift2_mmi, \
+ OP ## vc1_shift3_mmi }; \
+ \
+ if (vmode) { /* Vertical filter to apply */ \
+ if (hmode) { /* Horizontal filter to apply, output to tmp */ \
+ static const int shift_value[] = { 0, 5, 1, 5 }; \
+ int shift = (shift_value[hmode]+shift_value[vmode])>>1; \
+ int r; \
+ LOCAL_ALIGNED(16, int16_t, tmp, [12*8]); \
+ \
+ r = (1<<(shift-1)) + rnd-1; \
+ vc1_put_shift_ver_16bits[vmode](tmp, src-1, stride, r, shift); \
+ \
+ vc1_put_shift_hor_16bits[hmode](dst, stride, tmp+1, 64-rnd); \
+ return; \
+ } \
+ else { /* No horizontal filter, output 8 lines to dst */ \
+ vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride); \
+ return; \
+ } \
+ } \
+ \
+ /* Horizontal mode with no vertical mode */ \
+ vc1_put_shift_8bits[hmode](dst, src, stride, rnd, 1); \
+} \
+static void OP ## vc1_mspel_mc_16(uint8_t *dst, const uint8_t *src, \
+ int stride, int hmode, int vmode, int rnd)\
+{ \
+ OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \
+ OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \
+ dst += 8*stride; src += 8*stride; \
+ OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \
+ OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \
+}
+
+VC1_MSPEL_MC(put_)
+VC1_MSPEL_MC(avg_)
+
+/** Macro to ease bicubic filter interpolation functions declarations */
+#define DECLARE_FUNCTION(a, b) \
+void ff_put_vc1_mspel_mc ## a ## b ## _mmi(uint8_t *dst, \
+ const uint8_t *src, \
+ ptrdiff_t stride, \
+ int rnd) \
+{ \
+ put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
+} \
+void ff_avg_vc1_mspel_mc ## a ## b ## _mmi(uint8_t *dst, \
+ const uint8_t *src, \
+ ptrdiff_t stride, \
+ int rnd) \
+{ \
+ avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \
+} \
+void ff_put_vc1_mspel_mc ## a ## b ## _16_mmi(uint8_t *dst, \
+ const uint8_t *src, \
+ ptrdiff_t stride, \
+ int rnd) \
+{ \
+ put_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
+} \
+void ff_avg_vc1_mspel_mc ## a ## b ## _16_mmi(uint8_t *dst, \
+ const uint8_t *src, \
+ ptrdiff_t stride, \
+ int rnd) \
+{ \
+ avg_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \
+}
+
+DECLARE_FUNCTION(0, 1)
+DECLARE_FUNCTION(0, 2)
+DECLARE_FUNCTION(0, 3)
+
+DECLARE_FUNCTION(1, 0)
+DECLARE_FUNCTION(1, 1)
+DECLARE_FUNCTION(1, 2)
+DECLARE_FUNCTION(1, 3)
+
+DECLARE_FUNCTION(2, 0)
+DECLARE_FUNCTION(2, 1)
+DECLARE_FUNCTION(2, 2)
+DECLARE_FUNCTION(2, 3)
+
+DECLARE_FUNCTION(3, 0)
+DECLARE_FUNCTION(3, 1)
+DECLARE_FUNCTION(3, 2)
+DECLARE_FUNCTION(3, 3)
+
+#define CHROMA_MC_8_MMI \
+ "punpckhbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp8], %[ftmp4], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" \
+ \
+ "pmullh %[ftmp1], %[ftmp1], %[A] \n\t" \
+ "pmullh %[ftmp5], %[ftmp5], %[A] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[B] \n\t" \
+ "pmullh %[ftmp6], %[ftmp6], %[B] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[C] \n\t" \
+ "pmullh %[ftmp7], %[ftmp7], %[C] \n\t" \
+ "pmullh %[ftmp4], %[ftmp4], %[D] \n\t" \
+ "pmullh %[ftmp8], %[ftmp8], %[D] \n\t" \
+ \
+ "paddh %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \
+ "paddh %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ "paddh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \
+ "paddh %[ftmp1], %[ftmp1], %[ff_pw_28] \n\t" \
+ \
+ "paddh %[ftmp5], %[ftmp5], %[ftmp6] \n\t" \
+ "paddh %[ftmp7], %[ftmp7], %[ftmp8] \n\t" \
+ "paddh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \
+ "paddh %[ftmp5], %[ftmp5], %[ff_pw_28] \n\t" \
+ \
+ "psrlh %[ftmp1], %[ftmp1], %[ftmp9] \n\t" \
+ "psrlh %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \
+ "packushb %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
+
+
+#define CHROMA_MC_4_MMI \
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t" \
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" \
+ \
+ "pmullh %[ftmp1], %[ftmp1], %[A] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[B] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[C] \n\t" \
+ "pmullh %[ftmp4], %[ftmp4], %[D] \n\t" \
+ \
+ "paddh %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \
+ "paddh %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ "paddh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \
+ "paddh %[ftmp1], %[ftmp1], %[ff_pw_28] \n\t" \
+ \
+ "psrlh %[ftmp1], %[ftmp1], %[ftmp5] \n\t" \
+ "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+
+
+void ff_put_no_rnd_vc1_chroma_mc8_mmi(uint8_t *dst /* align 8 */,
+ uint8_t *src /* align 1 */,
+ int 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);
+ double ftmp[10];
+ uint32_t tmp[1];
+ DECLARE_VAR_ALL64;
+ DECLARE_VAR_ADDRT;
+
+ av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ __asm__ volatile(
+ "li %[tmp0], 0x06 \n\t"
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[tmp0], %[ftmp9] \n\t"
+ "pshufh %[A], %[A], %[ftmp0] \n\t"
+ "pshufh %[B], %[B], %[ftmp0] \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)
+
+ CHROMA_MC_8_MMI
+
+ MMI_SDC1(%[ftmp1], %[dst], 0x00)
+ "addiu %[h], %[h], -0x01 \n\t"
+ 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]),
+ RESTRICT_ASM_ALL64
+ RESTRICT_ASM_ADDRT
+ [tmp0]"=&r"(tmp[0]),
+ [src]"+&r"(src), [dst]"+&r"(dst),
+ [h]"+&r"(h)
+ : [stride]"r"((mips_reg)stride),
+ [A]"f"(A), [B]"f"(B),
+ [C]"f"(C), [D]"f"(D),
+ [ff_pw_28]"f"(ff_pw_28)
+ : "memory"
+ );
+}
+
+void ff_put_no_rnd_vc1_chroma_mc4_mmi(uint8_t *dst /* align 8 */,
+ uint8_t *src /* align 1 */,
+ int 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);
+ double ftmp[6];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ADDRT;
+
+ av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ __asm__ volatile(
+ "li %[tmp0], 0x06 \n\t"
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[tmp0], %[ftmp5] \n\t"
+ "pshufh %[A], %[A], %[ftmp0] \n\t"
+ "pshufh %[B], %[B], %[ftmp0] \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)
+
+ CHROMA_MC_4_MMI
+
+ MMI_SWC1(%[ftmp1], %[dst], 0x00)
+ "addiu %[h], %[h], -0x01 \n\t"
+ 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
+ RESTRICT_ASM_ADDRT
+ [src]"+&r"(src), [dst]"+&r"(dst),
+ [h]"+&r"(h)
+ : [stride]"r"((mips_reg)stride),
+ [A]"f"(A), [B]"f"(B),
+ [C]"f"(C), [D]"f"(D),
+ [ff_pw_28]"f"(ff_pw_28)
+ : "memory"
+ );
+}
+
+void ff_avg_no_rnd_vc1_chroma_mc8_mmi(uint8_t *dst /* align 8 */,
+ uint8_t *src /* align 1 */,
+ int 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);
+ double ftmp[10];
+ uint32_t tmp[1];
+ DECLARE_VAR_ALL64;
+ DECLARE_VAR_ADDRT;
+
+ av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ __asm__ volatile(
+ "li %[tmp0], 0x06 \n\t"
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[tmp0], %[ftmp9] \n\t"
+ "pshufh %[A], %[A], %[ftmp0] \n\t"
+ "pshufh %[B], %[B], %[ftmp0] \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)
+
+ CHROMA_MC_8_MMI
+
+ MMI_LDC1(%[ftmp2], %[dst], 0x00)
+ "pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
+
+ MMI_SDC1(%[ftmp1], %[dst], 0x00)
+ "addiu %[h], %[h], -0x01 \n\t"
+ 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]),
+ RESTRICT_ASM_ALL64
+ RESTRICT_ASM_ADDRT
+ [src]"+&r"(src), [dst]"+&r"(dst),
+ [h]"+&r"(h)
+ : [stride]"r"((mips_reg)stride),
+ [A]"f"(A), [B]"f"(B),
+ [C]"f"(C), [D]"f"(D),
+ [ff_pw_28]"f"(ff_pw_28)
+ : "memory"
+ );
+}
+
+void ff_avg_no_rnd_vc1_chroma_mc4_mmi(uint8_t *dst /* align 8 */,
+ uint8_t *src /* align 1 */,
+ int 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);
+ double ftmp[6];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ADDRT;
+
+ av_assert2(x < 8 && y < 8 && x >= 0 && y >= 0);
+
+ __asm__ volatile(
+ "li %[tmp0], 0x06 \n\t"
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[tmp0], %[ftmp5] \n\t"
+ "pshufh %[A], %[A], %[ftmp0] \n\t"
+ "pshufh %[B], %[B], %[ftmp0] \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)
+
+ CHROMA_MC_4_MMI
+
+ MMI_LWC1(%[ftmp2], %[dst], 0x00)
+ "pavgb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
+
+ MMI_SWC1(%[ftmp1], %[dst], 0x00)
+ "addiu %[h], %[h], -0x01 \n\t"
+ 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
+ RESTRICT_ASM_ADDRT
+ [src]"+&r"(src), [dst]"+&r"(dst),
+ [h]"+&r"(h)
+ : [stride]"r"((mips_reg)stride),
+ [A]"f"(A), [B]"f"(B),
+ [C]"f"(C), [D]"f"(D),
+ [ff_pw_28]"f"(ff_pw_28)
+ : "memory"
+ );
+}
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index 2d7e9b7..8f48f0c 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -1034,4 +1034,6 @@ av_cold void ff_vc1dsp_init(VC1DSPContext *dsp)
ff_vc1dsp_init_ppc(dsp);
if (ARCH_X86)
ff_vc1dsp_init_x86(dsp);
+ if (ARCH_MIPS)
+ ff_vc1dsp_init_mips(dsp);
}
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index 3d48f09..9543070 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -87,5 +87,6 @@ void ff_vc1dsp_init_aarch64(VC1DSPContext* dsp);
void ff_vc1dsp_init_arm(VC1DSPContext* dsp);
void ff_vc1dsp_init_ppc(VC1DSPContext *c);
void ff_vc1dsp_init_x86(VC1DSPContext* dsp);
+void ff_vc1dsp_init_mips(VC1DSPContext* dsp);
#endif /* AVCODEC_VC1DSP_H */
--
2.1.0
2
1
Hello,
In attach patch to add decoding of .psd file (Photoshop file).
PSD file can contain merge layers data at the end of the file (Image Data
Section)
This patch add support for this kind of files, using uncompress data Image
Data Section
Support Gray/A, and RGB/A with 8b or 16 bits by channel.
Samples can be found here :
https://we.tl/GK6yQhUV8j
Comments welcome
Martin
16
68
[PATCH 6/7] avcodec/mips: version 1 of wmv2dsp optimizations for loongson mmi
by 周晓勇 13 Dec '16
by 周晓勇 13 Dec '16
13 Dec '16
From 9b19ea3364d96a6eb0f3441f549c8d20ede36592 Mon Sep 17 00:00:00 2001
From: Zhou Xiaoyong <zhouxiaoyong(a)loongson.cn>
Date: Mon, 10 Oct 2016 15:04:35 +0800
Subject: [PATCH 6/7] avcodec/mips: version 1 of wmv2dsp optimizations for
loongson mmi
---
libavcodec/mips/Makefile | 2 +
libavcodec/mips/wmv2dsp_init_mips.c | 38 +++++
libavcodec/mips/wmv2dsp_mips.h | 29 ++++
libavcodec/mips/wmv2dsp_mmi.c | 278 ++++++++++++++++++++++++++++++++++++
libavcodec/wmv2dsp.c | 3 +
libavcodec/wmv2dsp.h | 1 +
6 files changed, 351 insertions(+)
create mode 100644 libavcodec/mips/wmv2dsp_init_mips.c
create mode 100644 libavcodec/mips/wmv2dsp_mips.h
create mode 100644 libavcodec/mips/wmv2dsp_mmi.c
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index cf54f38..2b6f37e 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -36,6 +36,7 @@ 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_WMV2DSP) += mips/wmv2dsp_init_mips.o
MSA-OBJS-$(CONFIG_HEVC_DECODER) += mips/hevcdsp_msa.o \
mips/hevc_mc_uni_msa.o \
mips/hevc_mc_uniw_msa.o \
@@ -79,3 +80,4 @@ 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_WMV2DSP) += mips/wmv2dsp_mmi.o
diff --git a/libavcodec/mips/wmv2dsp_init_mips.c b/libavcodec/mips/wmv2dsp_init_mips.c
new file mode 100644
index 0000000..51dd207
--- /dev/null
+++ b/libavcodec/mips/wmv2dsp_init_mips.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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 "wmv2dsp_mips.h"
+
+#if HAVE_MMI
+static av_cold void wmv2dsp_init_mmi(WMV2DSPContext *c)
+{
+ c->idct_add = ff_wmv2_idct_add_mmi;
+ c->idct_put = ff_wmv2_idct_put_mmi;
+}
+#endif /* HAVE_MMI */
+
+av_cold void ff_wmv2dsp_init_mips(WMV2DSPContext *c)
+{
+#if HAVE_MMI
+ wmv2dsp_init_mmi(c);
+#endif /* HAVE_MMI */
+}
diff --git a/libavcodec/mips/wmv2dsp_mips.h b/libavcodec/mips/wmv2dsp_mips.h
new file mode 100644
index 0000000..22894c5
--- /dev/null
+++ b/libavcodec/mips/wmv2dsp_mips.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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_WMV2DSP_MIPS_H
+#define AVCODEC_MIPS_WMV2DSP_MIPS_H
+
+#include "libavcodec/wmv2dsp.h"
+
+void ff_wmv2_idct_add_mmi(uint8_t *dest, int line_size, int16_t *block);
+void ff_wmv2_idct_put_mmi(uint8_t *dest, int line_size, int16_t *block);
+
+#endif /* AVCODEC_MIPS_WMV2DSP_MIPS_H */
diff --git a/libavcodec/mips/wmv2dsp_mmi.c b/libavcodec/mips/wmv2dsp_mmi.c
new file mode 100644
index 0000000..1f6ccb2
--- /dev/null
+++ b/libavcodec/mips/wmv2dsp_mmi.c
@@ -0,0 +1,278 @@
+/*
+ * WMV2 - DSP functions Loongson MMI-optimized
+ *
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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/avassert.h"
+#include "constants.h"
+#include "wmv2dsp_mips.h"
+#include "libavutil/mips/mmiutils.h"
+
+#define W0 2048
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+static void wmv2_idct_row_mmi(short * b)
+{
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1 */
+ a0 = W0 * b[0] + W0 * b[4];
+ a1 = W1 * b[1] + W7 * b[7];
+ a2 = W2 * b[2] + W6 * b[6];
+ a3 = W3 * b[5] - W5 * b[3];
+ a4 = W0 * b[0] - W0 * b[4];
+ a5 = W5 * b[5] + W3 * b[3];
+ a6 = W6 * b[2] - W2 * b[6];
+ a7 = W7 * b[1] - W1 * b[7];
+
+ /* step 2 */
+ s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
+ s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[0] = (a0 + a2 + a1 + a5 + 128) >> 8;
+ b[1] = (a4 + a6 + s1 + 128) >> 8;
+ b[2] = (a4 - a6 + s2 + 128) >> 8;
+ b[3] = (a0 - a2 + a7 + a3 + 128) >> 8;
+ b[4] = (a0 - a2 - a7 - a3 + 128) >> 8;
+ b[5] = (a4 - a6 - s2 + 128) >> 8;
+ b[6] = (a4 + a6 - s1 + 128) >> 8;
+ b[7] = (a0 + a2 - a1 - a5 + 128) >> 8;
+}
+
+static void wmv2_idct_col_mmi(short * b)
+{
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1, with extended precision */
+ a0 = (W0 * b[ 0] + W0 * b[32] ) >> 3;
+ a1 = (W1 * b[ 8] + W7 * b[56] + 4) >> 3;
+ a2 = (W2 * b[16] + W6 * b[48] + 4) >> 3;
+ a3 = (W3 * b[40] - W5 * b[24] + 4) >> 3;
+ a4 = (W0 * b[ 0] - W0 * b[32] ) >> 3;
+ a5 = (W5 * b[40] + W3 * b[24] + 4) >> 3;
+ a6 = (W6 * b[16] - W2 * b[48] + 4) >> 3;
+ a7 = (W7 * b[ 8] - W1 * b[56] + 4) >> 3;
+
+ /* step 2 */
+ s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8;
+ s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[ 0] = (a0 + a2 + a1 + a5 + 8192) >> 14;
+ b[ 8] = (a4 + a6 + s1 + 8192) >> 14;
+ b[16] = (a4 - a6 + s2 + 8192) >> 14;
+ b[24] = (a0 - a2 + a7 + a3 + 8192) >> 14;
+
+ b[32] = (a0 - a2 - a7 - a3 + 8192) >> 14;
+ b[40] = (a4 - a6 - s2 + 8192) >> 14;
+ b[48] = (a4 + a6 - s1 + 8192) >> 14;
+ b[56] = (a0 + a2 - a1 - a5 + 8192) >> 14;
+}
+
+void ff_wmv2_idct_add_mmi(uint8_t *dest, int line_size, int16_t *block)
+{
+ int i;
+ double ftmp[11];
+
+ for (i = 0; i < 64; i += 8)
+ wmv2_idct_row_mmi(block + i);
+ for (i = 0; i < 8; i++)
+ wmv2_idct_col_mmi(block + i);
+
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+
+ // low 4 loop
+ MMI_LDC1(%[ftmp1], %[block], 0x00)
+ MMI_LDC1(%[ftmp2], %[block], 0x08)
+ MMI_LDC1(%[ftmp3], %[block], 0x10)
+ MMI_LDC1(%[ftmp4], %[block], 0x18)
+ MMI_LDC1(%[ftmp5], %[block], 0x20)
+ MMI_LDC1(%[ftmp6], %[block], 0x28)
+ MMI_LDC1(%[ftmp7], %[block], 0x30)
+ MMI_LDC1(%[ftmp8], %[block], 0x38)
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
+ "packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
+ MMI_SDC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
+ "paddh %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
+ MMI_SDC1(%[ftmp3], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp5], %[ftmp5], %[ftmp9] \n\t"
+ "paddh %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
+ "packushb %[ftmp5], %[ftmp5], %[ftmp6] \n\t"
+ MMI_SDC1(%[ftmp5], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
+ "paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t"
+ "packushb %[ftmp7], %[ftmp7], %[ftmp8] \n\t"
+ MMI_SDC1(%[ftmp7], %[dest], 0x00)
+
+ PTR_ADDIU "%[block], %[block], 0x40 \n\t"
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ // high 4 loop
+ MMI_LDC1(%[ftmp1], %[block], 0x00)
+ MMI_LDC1(%[ftmp2], %[block], 0x08)
+ MMI_LDC1(%[ftmp3], %[block], 0x10)
+ MMI_LDC1(%[ftmp4], %[block], 0x18)
+ MMI_LDC1(%[ftmp5], %[block], 0x20)
+ MMI_LDC1(%[ftmp6], %[block], 0x28)
+ MMI_LDC1(%[ftmp7], %[block], 0x30)
+ MMI_LDC1(%[ftmp8], %[block], 0x38)
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
+ "packushb %[ftmp1], %[ftmp1], %[ftmp2] \n\t"
+ MMI_SDC1(%[ftmp1], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ftmp9] \n\t"
+ "paddh %[ftmp4], %[ftmp4], %[ftmp10] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp4] \n\t"
+ MMI_SDC1(%[ftmp3], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp5], %[ftmp5], %[ftmp9] \n\t"
+ "paddh %[ftmp6], %[ftmp6], %[ftmp10] \n\t"
+ "packushb %[ftmp5], %[ftmp5], %[ftmp6] \n\t"
+ MMI_SDC1(%[ftmp5], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ MMI_LDC1(%[ftmp9], %[dest], 0x00)
+ "punpckhbh %[ftmp10], %[ftmp9], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t"
+ "paddh %[ftmp7], %[ftmp7], %[ftmp9] \n\t"
+ "paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t"
+ "packushb %[ftmp7], %[ftmp7], %[ftmp8] \n\t"
+ MMI_SDC1(%[ftmp7], %[dest], 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]),
+ [block]"+&r"(block), [dest]"+&r"(dest)
+ : [line_size]"r"((mips_reg)line_size)
+ : "memory"
+ );
+}
+
+void ff_wmv2_idct_put_mmi(uint8_t *dest, int line_size, int16_t *block)
+{
+ int i;
+ double ftmp[8];
+
+ for (i = 0; i < 64; i += 8)
+ wmv2_idct_row_mmi(block + i);
+ for (i = 0; i < 8; i++)
+ wmv2_idct_col_mmi(block + i);
+
+ __asm__ volatile (
+ // low 4 loop
+ 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], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp2], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp4], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp6], %[dest], 0x00)
+
+ PTR_ADDIU "%[block], %[block], 0x40 \n\t"
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+
+ // high 4 loop
+ 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], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp2], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp4], %[dest], 0x00)
+ PTR_ADDU "%[dest], %[dest], %[line_size] \n\t"
+ MMI_SDC1(%[ftmp6], %[dest], 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]),
+ [block]"+&r"(block), [dest]"+&r"(dest)
+ : [line_size]"r"((mips_reg)line_size)
+ : "memory"
+ );
+}
diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c
index 40e0bef..b9e98d5 100644
--- a/libavcodec/wmv2dsp.c
+++ b/libavcodec/wmv2dsp.c
@@ -262,4 +262,7 @@ av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
c->put_mspel_pixels_tab[5] = put_mspel8_mc12_c;
c->put_mspel_pixels_tab[6] = put_mspel8_mc22_c;
c->put_mspel_pixels_tab[7] = put_mspel8_mc32_c;
+
+ if (ARCH_MIPS)
+ ff_wmv2dsp_init_mips(c);
}
diff --git a/libavcodec/wmv2dsp.h b/libavcodec/wmv2dsp.h
index 0bf9489..62a990d 100644
--- a/libavcodec/wmv2dsp.h
+++ b/libavcodec/wmv2dsp.h
@@ -33,5 +33,6 @@ typedef struct WMV2DSPContext {
} WMV2DSPContext;
void ff_wmv2dsp_init(WMV2DSPContext *c);
+void ff_wmv2dsp_init_mips(WMV2DSPContext *c);
#endif /* AVCODEC_WMV2DSP_H */
--
2.1.0
2
1
[PATCH 5/7] avcodec/mips: version 1 of vp8dsp optimizations for loongson mmi
by 周晓勇 13 Dec '16
by 周晓勇 13 Dec '16
13 Dec '16
From 4fc873738c8db1cf711310bc5767f7574302eb96 Mon Sep 17 00:00:00 2001
From: Zhou Xiaoyong <zhouxiaoyong(a)loongson.cn>
Date: Mon, 10 Oct 2016 14:50:08 +0800
Subject: [PATCH 5/7] avcodec/mips: version 1 of vp8dsp optimizations for
loongson mmi
---
libavcodec/mips/Makefile | 1 +
libavcodec/mips/constants.c | 1 +
libavcodec/mips/constants.h | 1 +
libavcodec/mips/vp8dsp_init_mips.c | 89 ++
libavcodec/mips/vp8dsp_mips.h | 117 ++
libavcodec/mips/vp8dsp_mmi.c | 3052 ++++++++++++++++++++++++++++++++++++
6 files changed, 3261 insertions(+)
create mode 100644 libavcodec/mips/vp8dsp_mmi.c
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index 3c43600..cf54f38 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -77,4 +77,5 @@ 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
diff --git a/libavcodec/mips/constants.c b/libavcodec/mips/constants.c
index 3503fad..9c10d29 100644
--- a/libavcodec/mips/constants.c
+++ b/libavcodec/mips/constants.c
@@ -28,6 +28,7 @@ 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};
diff --git a/libavcodec/mips/constants.h b/libavcodec/mips/constants.h
index 19d2d73..e164ecb 100644
--- a/libavcodec/mips/constants.h
+++ b/libavcodec/mips/constants.h
@@ -29,6 +29,7 @@ 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;
diff --git a/libavcodec/mips/vp8dsp_init_mips.c b/libavcodec/mips/vp8dsp_init_mips.c
index 58d1b6c..3fc5f8e 100644
--- a/libavcodec/mips/vp8dsp_init_mips.c
+++ b/libavcodec/mips/vp8dsp_init_mips.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale(a)imgtec.com)
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)loongson.cn>
*
* This file is part of FFmpeg.
*
@@ -105,9 +106,97 @@ static av_cold void vp8dsp_init_msa(VP8DSPContext *dsp)
}
#endif // #if HAVE_MSA
+#if HAVE_MMI
+static av_cold void vp8dsp_init_mmi(VP8DSPContext *dsp)
+{
+ dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmi;
+ dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_mmi;
+ dsp->vp8_idct_add = ff_vp8_idct_add_mmi;
+ dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmi;
+ dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmi;
+ dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmi;
+
+ dsp->put_vp8_epel_pixels_tab[0][0][1] = ff_put_vp8_epel16_h4_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][1][0] = ff_put_vp8_epel16_v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][1][1] = ff_put_vp8_epel16_h4v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][1][2] = ff_put_vp8_epel16_h6v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][2][1] = ff_put_vp8_epel16_h4v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_mmi;
+
+ dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_mmi;
+
+ dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_mmi;
+ dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_mmi;
+
+ dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilinear16_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilinear16_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilinear16_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilinear16_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilinear16_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilinear16_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilinear16_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilinear16_hv_mmi;
+
+ dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilinear8_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilinear8_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilinear8_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilinear8_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilinear8_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilinear8_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilinear8_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilinear8_hv_mmi;
+
+ dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilinear4_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilinear4_h_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilinear4_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilinear4_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilinear4_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilinear4_v_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilinear4_hv_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilinear4_hv_mmi;
+
+ dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmi;
+
+ dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi;
+ dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmi;
+
+ dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_mmi;
+ dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_mmi;
+ dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mmi;
+ dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mmi;
+
+ dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_mmi;
+ dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_mmi;
+ dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmi;
+ dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmi;
+
+ dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmi;
+ dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmi;
+}
+#endif /* HAVE_MMI */
+
av_cold void ff_vp8dsp_init_mips(VP8DSPContext *dsp)
{
#if HAVE_MSA
vp8dsp_init_msa(dsp);
#endif // #if HAVE_MSA
+#if HAVE_MMI
+ vp8dsp_init_mmi(dsp);
+#endif /* HAVE_MMI */
}
diff --git a/libavcodec/mips/vp8dsp_mips.h b/libavcodec/mips/vp8dsp_mips.h
index 8e715b5..07666ab 100644
--- a/libavcodec/mips/vp8dsp_mips.h
+++ b/libavcodec/mips/vp8dsp_mips.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale(a)imgtec.com)
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)loongson.cn>
*
* This file is part of FFmpeg.
*
@@ -21,6 +22,11 @@
#ifndef AVCODEC_MIPS_VP8DSP_MIPS_H
#define AVCODEC_MIPS_VP8DSP_MIPS_H
+#include "libavutil/mem.h"
+#include "libavcodec/vp8dsp.h"
+#include "libavcodec/mathops.h"
+#include "constants.h"
+
void ff_put_vp8_pixels4_msa(uint8_t *dst, ptrdiff_t dststride,
uint8_t *src, ptrdiff_t srcstride,
int h, int x, int y);
@@ -169,4 +175,115 @@ void ff_vp8_idct_dc_add4uv_msa(uint8_t *dst, int16_t block[4][16],
void ff_vp8_idct_dc_add4y_msa(uint8_t *dst, int16_t block[4][16],
ptrdiff_t stride);
+void ff_vp8_luma_dc_wht_mmi(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_luma_dc_wht_dc_mmi(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_idct_add_mmi(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add_mmi(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_mmi(uint8_t *dst, int16_t block[4][16],
+ ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_mmi(uint8_t *dst, int16_t block[4][16],
+ ptrdiff_t stride);
+
+void ff_put_vp8_pixels4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y);
+void ff_put_vp8_pixels8_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y);
+void ff_put_vp8_pixels16_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y);
+
+void ff_put_vp8_epel16_h4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_h6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel16_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+void ff_put_vp8_epel8_h4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_h6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel8_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+void ff_put_vp8_epel4_h4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_h6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_epel4_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+void ff_put_vp8_bilinear16_h_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear16_v_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear16_hv_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+void ff_put_vp8_bilinear8_h_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear8_v_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear8_hv_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+void ff_put_vp8_bilinear4_h_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear4_v_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+void ff_put_vp8_bilinear4_hv_mmi(uint8_t *dst, ptrdiff_t dststride,
+ uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my);
+
+// loop filter applied to edges between macroblocks
+void ff_vp8_v_loop_filter16_mmi(uint8_t *dst, ptrdiff_t stride, int flim_E,
+ int flim_I, int hev_thresh);
+void ff_vp8_h_loop_filter16_mmi(uint8_t *dst, ptrdiff_t stride, int flim_E,
+ int flim_I, int hev_thresh);
+void ff_vp8_v_loop_filter8uv_mmi(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh);
+void ff_vp8_h_loop_filter8uv_mmi(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh);
+
+// loop filter applied to inner macroblock edges
+void ff_vp8_v_loop_filter16_inner_mmi(uint8_t *dst, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh);
+void ff_vp8_h_loop_filter16_inner_mmi(uint8_t *dst, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh);
+void ff_vp8_v_loop_filter8uv_inner_mmi(uint8_t *dstU, uint8_t *dstV,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh);
+void ff_vp8_h_loop_filter8uv_inner_mmi(uint8_t *dstU, uint8_t *dstV,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh);
+
+void ff_vp8_v_loop_filter_simple_mmi(uint8_t *dst, ptrdiff_t stride, int flim);
+void ff_vp8_h_loop_filter_simple_mmi(uint8_t *dst, ptrdiff_t stride, int flim);
+
#endif // #ifndef AVCODEC_MIPS_VP8DSP_MIPS_H
diff --git a/libavcodec/mips/vp8dsp_mmi.c b/libavcodec/mips/vp8dsp_mmi.c
new file mode 100644
index 0000000..f972628
--- /dev/null
+++ b/libavcodec/mips/vp8dsp_mmi.c
@@ -0,0 +1,3052 @@
+/*
+ * Loongson SIMD optimized vp8dsp
+ *
+ * Copyright (c) 2016 Loongson Technology Corporation Limited
+ * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong(a)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 "vp8dsp_mips.h"
+#include "constants.h"
+#include "libavutil/mips/mmiutils.h"
+
+#define PUT_VP8_EPEL4_H6_MMI(src, dst) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, -0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "psubsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, -0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter0] \n\t" \
+ "paddsh %[ftmp5], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter3] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "psubsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x03) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter5] \n\t" \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp5] \n\t" \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL4_H4_MMI(src, dst) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, -0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "psubsh %[ftmp5], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter3] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "psubh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp5] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL4_V6_MMI(src, src1, dst, srcstride) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter2] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "psubsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter0] \n\t" \
+ "paddsh %[ftmp5], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "psubsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter5] \n\t" \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp5] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL4_V4_MMI(src, src1, dst, srcstride) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter2] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "psubsh %[ftmp5], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[filter3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "psubsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp5] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL8_H6_MMI(src, dst) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter2] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter2] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, -0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter1] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, -0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter0] \n\t" \
+ "paddsh %[ftmp7], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp8], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter3] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter4] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x03) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter5] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter5] \n\t" \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_64] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL8_H4_MMI(src, dst) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter2] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter2] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, -0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter1] \n\t" \
+ "psubsh %[ftmp7], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp8], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter3] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter3] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x02) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter4] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_64] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL8_V6_MMI(src, src1, dst, srcstride) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter2] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter2] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter1] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter0] \n\t" \
+ "paddsh %[ftmp7], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp8], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter3] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter4] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter5] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter5] \n\t" \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_64] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_EPEL8_V4_MMI(src, src1, dst, srcstride) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter2] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter2] \n\t" \
+ \
+ PTR_SUBU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter1] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter1] \n\t" \
+ "psubsh %[ftmp7], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp8], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[filter3] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[filter3] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src1", "#srcstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[filter4] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[filter4] \n\t" \
+ "psubsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "psubsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_64] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_64] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_BILINEAR8_H_MMI(src, dst) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[a] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[a] \n\t" \
+ \
+ MMI_ULDC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[b] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[b] \n\t" \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_4] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_4] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_BILINEAR4_H_MMI(src, dst) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[a] \n\t" \
+ \
+ MMI_ULWC1(%[ftmp1], src, 0x01) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[b] \n\t" \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_4] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_BILINEAR8_V_MMI(src, src1, dst, sstride) \
+ MMI_ULDC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp5], %[ftmp2], %[c] \n\t" \
+ "pmullh %[ftmp6], %[ftmp3], %[c] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#sstride" \n\t" \
+ MMI_ULDC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[d] \n\t" \
+ "pmullh %[ftmp3], %[ftmp3], %[d] \n\t" \
+ "paddsh %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" \
+ \
+ "paddsh %[ftmp5], %[ftmp5], %[ff_pw_4] \n\t" \
+ "paddsh %[ftmp6], %[ftmp6], %[ff_pw_4] \n\t" \
+ "psrah %[ftmp5], %[ftmp5], %[ftmp4] \n\t" \
+ "psrah %[ftmp6], %[ftmp6], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp5], %[ftmp6] \n\t" \
+ MMI_SDC1(%[ftmp1], dst, 0x00)
+
+
+#define PUT_VP8_BILINEAR4_V_MMI(src, src1, dst, sstride) \
+ MMI_ULWC1(%[ftmp1], src, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp3], %[ftmp2], %[c] \n\t" \
+ \
+ PTR_ADDU ""#src1", "#src", "#sstride" \n\t" \
+ MMI_ULWC1(%[ftmp1], src1, 0x00) \
+ "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \
+ "pmullh %[ftmp2], %[ftmp2], %[d] \n\t" \
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp2] \n\t" \
+ \
+ "paddsh %[ftmp3], %[ftmp3], %[ff_pw_4] \n\t" \
+ "psrah %[ftmp3], %[ftmp3], %[ftmp4] \n\t" \
+ \
+ "packushb %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \
+ MMI_SWC1(%[ftmp1], dst, 0x00)
+
+
+DECLARE_ALIGNED(8, static const uint64_t, fourtap_subpel_filters[7][6]) = {
+ {0x0000000000000000, 0x0006000600060006, 0x007b007b007b007b,
+ 0x000c000c000c000c, 0x0001000100010001, 0x0000000000000000},
+
+ {0x0002000200020002, 0x000b000b000b000b, 0x006c006c006c006c,
+ 0x0024002400240024, 0x0008000800080008, 0x0001000100010001},
+
+ {0x0000000000000000, 0x0009000900090009, 0x005d005d005d005d,
+ 0x0032003200320032, 0x0006000600060006, 0x0000000000000000},
+
+ {0x0003000300030003, 0x0010001000100010, 0x004d004d004d004d,
+ 0x004d004d004d004d, 0x0010001000100010, 0x0003000300030003},
+
+ {0x0000000000000000, 0x0006000600060006, 0x0032003200320032,
+ 0x005d005d005d005d, 0x0009000900090009, 0x0000000000000000},
+
+ {0x0001000100010001, 0x0008000800080008, 0x0024002400240024,
+ 0x006c006c006c006c, 0x000b000b000b000b, 0x0002000200020002},
+
+ {0x0000000000000000, 0x0001000100010001, 0x000c000c000c000c,
+ 0x007b007b007b007b, 0x0006000600060006, 0x0000000000000000}
+};
+
+#if 0
+#define FILTER_6TAP(src, F, stride) \
+ cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
+ F[0] * src[x - 2 * stride] + F[3] * src[x + 1 * stride] - \
+ F[4] * src[x + 2 * stride] + F[5] * src[x + 3 * stride] + 64) >> 7]
+
+#define FILTER_4TAP(src, F, stride) \
+ cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
+ F[3] * src[x + 1 * stride] - F[4] * src[x + 2 * stride] + 64) >> 7]
+
+static const uint8_t subpel_filters[7][6] = {
+ { 0, 6, 123, 12, 1, 0 },
+ { 2, 11, 108, 36, 8, 1 },
+ { 0, 9, 93, 50, 6, 0 },
+ { 3, 16, 77, 77, 16, 3 },
+ { 0, 6, 50, 93, 9, 0 },
+ { 1, 8, 36, 108, 11, 2 },
+ { 0, 1, 12, 123, 6, 0 },
+};
+
+#define MUL_20091(a) ((((a) * 20091) >> 16) + (a))
+#define MUL_35468(a) (((a) * 35468) >> 16)
+#endif
+
+#define clip_int8(n) (cm[(n) + 0x80] - 0x80)
+static av_always_inline void vp8_filter_common_is4tap(uint8_t *p,
+ ptrdiff_t stride)
+{
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+ int a, f1, f2;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ a = 3 * (q0 - p0);
+ a += clip_int8(p1 - q1);
+ a = clip_int8(a);
+
+ // We deviate from the spec here with c(a+3) >> 3
+ // since that's what libvpx does.
+ f1 = FFMIN(a + 4, 127) >> 3;
+ f2 = FFMIN(a + 3, 127) >> 3;
+
+ // Despite what the spec says, we do need to clamp here to
+ // be bitexact with libvpx.
+ p[-1 * stride] = cm[p0 + f2];
+ p[ 0 * stride] = cm[q0 - f1];
+}
+
+static av_always_inline void vp8_filter_common_isnot4tap(uint8_t *p,
+ ptrdiff_t stride)
+{
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+ int a, f1, f2;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ a = 3 * (q0 - p0);
+ a = clip_int8(a);
+
+ // We deviate from the spec here with c(a+3) >> 3
+ // since that's what libvpx does.
+ f1 = FFMIN(a + 4, 127) >> 3;
+ f2 = FFMIN(a + 3, 127) >> 3;
+
+ // Despite what the spec says, we do need to clamp here to
+ // be bitexact with libvpx.
+ p[-1 * stride] = cm[p0 + f2];
+ p[ 0 * stride] = cm[q0 - f1];
+ a = (f1 + 1) >> 1;
+ p[-2 * stride] = cm[p1 + a];
+ p[ 1 * stride] = cm[q1 - a];
+}
+
+static av_always_inline int vp8_simple_limit(uint8_t *p, ptrdiff_t stride,
+ int flim)
+{
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+
+ return 2 * FFABS(p0 - q0) + (FFABS(p1 - q1) >> 1) <= flim;
+}
+
+static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
+{
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+
+ return FFABS(p1 - p0) > thresh || FFABS(q1 - q0) > thresh;
+}
+
+static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
+{
+ int a0, a1, a2, w;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ int av_unused p2 = p[-3 * stride];
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+ int av_unused q2 = p[ 2 * stride];
+
+ w = clip_int8(p1 - q1);
+ w = clip_int8(w + 3 * (q0 - p0));
+
+ a0 = (27 * w + 63) >> 7;
+ a1 = (18 * w + 63) >> 7;
+ a2 = (9 * w + 63) >> 7;
+
+ p[-3 * stride] = cm[p2 + a2];
+ p[-2 * stride] = cm[p1 + a1];
+ p[-1 * stride] = cm[p0 + a0];
+ p[ 0 * stride] = cm[q0 - a0];
+ p[ 1 * stride] = cm[q1 - a1];
+ p[ 2 * stride] = cm[q2 - a2];
+}
+
+static av_always_inline int vp8_normal_limit(uint8_t *p, ptrdiff_t stride,
+ int E, int I)
+{
+ int av_unused p3 = p[-4 * stride];
+ int av_unused p2 = p[-3 * stride];
+ int av_unused p1 = p[-2 * stride];
+ int av_unused p0 = p[-1 * stride];
+ int av_unused q0 = p[ 0 * stride];
+ int av_unused q1 = p[ 1 * stride];
+ int av_unused q2 = p[ 2 * stride];
+ int av_unused q3 = p[ 3 * stride];
+
+ return vp8_simple_limit(p, stride, E) &&
+ FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I &&
+ FFABS(p1 - p0) <= I && FFABS(q3 - q2) <= I &&
+ FFABS(q2 - q1) <= I && FFABS(q1 - q0) <= I;
+}
+
+static av_always_inline void vp8_v_loop_filter8_mmi(uint8_t *dst,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ if (vp8_normal_limit(dst + i * 1, stride, flim_E, flim_I)) {
+ if (hev(dst + i * 1, stride, hev_thresh))
+ vp8_filter_common_is4tap(dst + i * 1, stride);
+ else
+ filter_mbedge(dst + i * 1, stride);
+ }
+}
+
+static av_always_inline void vp8_v_loop_filter8_inner_mmi(uint8_t *dst,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ if (vp8_normal_limit(dst + i * 1, stride, flim_E, flim_I)) {
+ int hv = hev(dst + i * 1, stride, hev_thresh);
+ if (hv)
+ vp8_filter_common_is4tap(dst + i * 1, stride);
+ else
+ vp8_filter_common_isnot4tap(dst + i * 1, stride);
+ }
+}
+
+static av_always_inline void vp8_h_loop_filter8_mmi(uint8_t *dst,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ if (vp8_normal_limit(dst + i * stride, 1, flim_E, flim_I)) {
+ if (hev(dst + i * stride, 1, hev_thresh))
+ vp8_filter_common_is4tap(dst + i * stride, 1);
+ else
+ filter_mbedge(dst + i * stride, 1);
+ }
+}
+
+static av_always_inline void vp8_h_loop_filter8_inner_mmi(uint8_t *dst,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ if (vp8_normal_limit(dst + i * stride, 1, flim_E, flim_I)) {
+ int hv = hev(dst + i * stride, 1, hev_thresh);
+ if (hv)
+ vp8_filter_common_is4tap(dst + i * stride, 1);
+ else
+ vp8_filter_common_isnot4tap(dst + i * stride, 1);
+ }
+}
+
+void ff_vp8_luma_dc_wht_mmi(int16_t block[4][4][16], int16_t dc[16])
+{
+#if 1
+ double ftmp[8];
+ DECLARE_VAR_ALL64;
+
+ __asm__ volatile (
+ MMI_LDC1(%[ftmp0], %[dc], 0x00)
+ MMI_LDC1(%[ftmp1], %[dc], 0x08)
+ MMI_LDC1(%[ftmp2], %[dc], 0x10)
+ MMI_LDC1(%[ftmp3], %[dc], 0x18)
+ "paddsh %[ftmp4], %[ftmp0], %[ftmp3] \n\t"
+ "psubsh %[ftmp5], %[ftmp0], %[ftmp3] \n\t"
+ "paddsh %[ftmp6], %[ftmp1], %[ftmp2] \n\t"
+ "psubsh %[ftmp7], %[ftmp1], %[ftmp2] \n\t"
+ "paddsh %[ftmp0], %[ftmp4], %[ftmp6] \n\t"
+ "paddsh %[ftmp1], %[ftmp5], %[ftmp7] \n\t"
+ "psubsh %[ftmp2], %[ftmp4], %[ftmp6] \n\t"
+ "psubsh %[ftmp3], %[ftmp5], %[ftmp7] \n\t"
+ MMI_SDC1(%[ftmp0], %[dc], 0x00)
+ MMI_SDC1(%[ftmp1], %[dc], 0x08)
+ MMI_SDC1(%[ftmp2], %[dc], 0x10)
+ MMI_SDC1(%[ftmp3], %[dc], 0x18)
+ : [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
+ [ftmp7]"=&f"(ftmp[7])
+ : [dc]"r"((uint8_t*)dc)
+ : "memory"
+ );
+
+ block[0][0][0] = (dc[0] + dc[3] + 3 + dc[1] + dc[2]) >> 3;
+ block[0][1][0] = (dc[0] - dc[3] + 3 + dc[1] - dc[2]) >> 3;
+ block[0][2][0] = (dc[0] + dc[3] + 3 - dc[1] - dc[2]) >> 3;
+ block[0][3][0] = (dc[0] - dc[3] + 3 - dc[1] + dc[2]) >> 3;
+
+ block[1][0][0] = (dc[4] + dc[7] + 3 + dc[5] + dc[6]) >> 3;
+ block[1][1][0] = (dc[4] - dc[7] + 3 + dc[5] - dc[6]) >> 3;
+ block[1][2][0] = (dc[4] + dc[7] + 3 - dc[5] - dc[6]) >> 3;
+ block[1][3][0] = (dc[4] - dc[7] + 3 - dc[5] + dc[6]) >> 3;
+
+ block[2][0][0] = (dc[8] + dc[11] + 3 + dc[9] + dc[10]) >> 3;
+ block[2][1][0] = (dc[8] - dc[11] + 3 + dc[9] - dc[10]) >> 3;
+ block[2][2][0] = (dc[8] + dc[11] + 3 - dc[9] - dc[10]) >> 3;
+ block[2][3][0] = (dc[8] - dc[11] + 3 - dc[9] + dc[10]) >> 3;
+
+ block[3][0][0] = (dc[12] + dc[15] + 3 + dc[13] + dc[14]) >> 3;
+ block[3][1][0] = (dc[12] - dc[15] + 3 + dc[13] - dc[14]) >> 3;
+ block[3][2][0] = (dc[12] + dc[15] + 3 - dc[13] - dc[14]) >> 3;
+ block[3][3][0] = (dc[12] - dc[15] + 3 - dc[13] + dc[14]) >> 3;
+
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ MMI_SDC1(%[ftmp0], %[dc], 0x00)
+ MMI_SDC1(%[ftmp0], %[dc], 0x08)
+ MMI_SDC1(%[ftmp0], %[dc], 0x10)
+ MMI_SDC1(%[ftmp0], %[dc], 0x18)
+ : RESTRICT_ASM_ALL64
+ [ftmp0]"=&f"(ftmp[0])
+ : [dc]"r"((uint8_t *)dc)
+ : "memory"
+ );
+#else
+ int t00, t01, t02, t03, t10, t11, t12, t13, t20, t21, t22, t23, t30, t31, t32, t33;
+
+ t00 = dc[0] + dc[12];
+ t10 = dc[1] + dc[13];
+ t20 = dc[2] + dc[14];
+ t30 = dc[3] + dc[15];
+
+ t03 = dc[0] - dc[12];
+ t13 = dc[1] - dc[13];
+ t23 = dc[2] - dc[14];
+ t33 = dc[3] - dc[15];
+
+ t01 = dc[4] + dc[ 8];
+ t11 = dc[5] + dc[ 9];
+ t21 = dc[6] + dc[10];
+ t31 = dc[7] + dc[11];
+
+ t02 = dc[4] - dc[ 8];
+ t12 = dc[5] - dc[ 9];
+ t22 = dc[6] - dc[10];
+ t32 = dc[7] - dc[11];
+
+ dc[ 0] = t00 + t01;
+ dc[ 1] = t10 + t11;
+ dc[ 2] = t20 + t21;
+ dc[ 3] = t30 + t31;
+
+ dc[ 4] = t03 + t02;
+ dc[ 5] = t13 + t12;
+ dc[ 6] = t23 + t22;
+ dc[ 7] = t33 + t32;
+
+ dc[ 8] = t00 - t01;
+ dc[ 9] = t10 - t11;
+ dc[10] = t20 - t21;
+ dc[11] = t30 - t31;
+
+ dc[12] = t03 - t02;
+ dc[13] = t13 - t12;
+ dc[14] = t23 - t22;
+ dc[15] = t33 - t32;
+
+ block[0][0][0] = (dc[0] + dc[3] + 3 + dc[1] + dc[2]) >> 3;
+ block[0][1][0] = (dc[0] - dc[3] + 3 + dc[1] - dc[2]) >> 3;
+ block[0][2][0] = (dc[0] + dc[3] + 3 - dc[1] - dc[2]) >> 3;
+ block[0][3][0] = (dc[0] - dc[3] + 3 - dc[1] + dc[2]) >> 3;
+
+ block[1][0][0] = (dc[4] + dc[7] + 3 + dc[5] + dc[6]) >> 3;
+ block[1][1][0] = (dc[4] - dc[7] + 3 + dc[5] - dc[6]) >> 3;
+ block[1][2][0] = (dc[4] + dc[7] + 3 - dc[5] - dc[6]) >> 3;
+ block[1][3][0] = (dc[4] - dc[7] + 3 - dc[5] + dc[6]) >> 3;
+
+ block[2][0][0] = (dc[8] + dc[11] + 3 + dc[9] + dc[10]) >> 3;
+ block[2][1][0] = (dc[8] - dc[11] + 3 + dc[9] - dc[10]) >> 3;
+ block[2][2][0] = (dc[8] + dc[11] + 3 - dc[9] - dc[10]) >> 3;
+ block[2][3][0] = (dc[8] - dc[11] + 3 - dc[9] + dc[10]) >> 3;
+
+ block[3][0][0] = (dc[12] + dc[15] + 3 + dc[13] + dc[14]) >> 3;
+ block[3][1][0] = (dc[12] - dc[15] + 3 + dc[13] - dc[14]) >> 3;
+ block[3][2][0] = (dc[12] + dc[15] + 3 - dc[13] - dc[14]) >> 3;
+ block[3][3][0] = (dc[12] - dc[15] + 3 - dc[13] + dc[14]) >> 3;
+
+ AV_ZERO64(dc + 0);
+ AV_ZERO64(dc + 4);
+ AV_ZERO64(dc + 8);
+ AV_ZERO64(dc + 12);
+#endif
+}
+
+void ff_vp8_luma_dc_wht_dc_mmi(int16_t block[4][4][16], int16_t dc[16])
+{
+ int val = (dc[0] + 3) >> 3;
+
+ dc[0] = 0;
+
+ block[0][0][0] = val;
+ block[0][1][0] = val;
+ block[0][2][0] = val;
+ block[0][3][0] = val;
+ block[1][0][0] = val;
+ block[1][1][0] = val;
+ block[1][2][0] = val;
+ block[1][3][0] = val;
+ block[2][0][0] = val;
+ block[2][1][0] = val;
+ block[2][2][0] = val;
+ block[2][3][0] = val;
+ block[3][0][0] = val;
+ block[3][1][0] = val;
+ block[3][2][0] = val;
+ block[3][3][0] = val;
+}
+
+void ff_vp8_idct_add_mmi(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+#if 1
+ DECLARE_ALIGNED(8, const uint64_t, ff_ph_4e7b) = {0x4e7b4e7b4e7b4e7bULL};
+ DECLARE_ALIGNED(8, const uint64_t, ff_ph_22a3) = {0x22a322a322a322a3ULL};
+ double ftmp[12];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ALL64;
+
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ MMI_LDC1(%[ftmp1], %[block], 0x00)
+ MMI_LDC1(%[ftmp2], %[block], 0x08)
+ MMI_LDC1(%[ftmp3], %[block], 0x10)
+ MMI_LDC1(%[ftmp4], %[block], 0x18)
+
+ "li %[tmp0], 0x02 \n\t"
+ "mtc1 %[tmp0], %[ftmp11] \n\t"
+
+ // block[0...3] + block[8...11]
+ "paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t"
+ // block[0...3] - block[8...11]
+ "psubh %[ftmp6], %[ftmp1], %[ftmp3] \n\t"
+ // MUL_35468(block[12...15])
+ "psllh %[ftmp9], %[ftmp4], %[ftmp11] \n\t"
+ "pmulhh %[ftmp7], %[ftmp9], %[ff_ph_22a3] \n\t"
+ // MUL_35468(block[4...7])
+ "psllh %[ftmp9], %[ftmp2], %[ftmp11] \n\t"
+ "pmulhh %[ftmp8], %[ftmp9], %[ff_ph_22a3] \n\t"
+ // MUL_20091(block[4...7]
+ "pmulhh %[ftmp9], %[ftmp2], %[ff_ph_4e7b] \n\t"
+ "paddh %[ftmp9], %[ftmp9], %[ftmp2] \n\t"
+ // MUL_20091(block[12...15])
+ "pmulhh %[ftmp10], %[ftmp4], %[ff_ph_4e7b] \n\t"
+ "paddh %[ftmp10], %[ftmp10], %[ftmp4] \n\t"
+
+ // tmp[0 4 8 12]
+ "paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t"
+ // tmp[1 5 9 13]
+ "paddh %[ftmp2], %[ftmp6], %[ftmp8] \n\t"
+ "psubh %[ftmp2], %[ftmp2], %[ftmp10] \n\t"
+ // tmp[2 6 10 14]
+ "psubh %[ftmp3], %[ftmp6], %[ftmp8] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ftmp10] \n\t"
+ // tmp[3 7 11 15]
+ "psubh %[ftmp4], %[ftmp5], %[ftmp7] \n\t"
+ "psubh %[ftmp4], %[ftmp4], %[ftmp9] \n\t"
+
+ MMI_SDC1(%[ftmp0], %[block], 0x00)
+ MMI_SDC1(%[ftmp0], %[block], 0x08)
+ MMI_SDC1(%[ftmp0], %[block], 0x10)
+ MMI_SDC1(%[ftmp0], %[block], 0x18)
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp0], %[ftmp10])
+
+ // t[0 4 8 12]
+ "paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t"
+ // t[1 5 9 13]
+ "psubh %[ftmp6], %[ftmp1], %[ftmp3] \n\t"
+ // t[2 6 10 14]
+ "psllh %[ftmp9], %[ftmp2], %[ftmp11] \n\t"
+ "pmulhh %[ftmp9], %[ftmp9], %[ff_ph_22a3] \n\t"
+ "psubh %[ftmp7], %[ftmp9], %[ftmp4] \n\t"
+ "pmulhh %[ftmp10], %[ftmp4], %[ff_ph_4e7b] \n\t"
+ "psubh %[ftmp7], %[ftmp7], %[ftmp10] \n\t"
+ // t[3 7 11 15]
+ "psllh %[ftmp9], %[ftmp4], %[ftmp11] \n\t"
+ "pmulhh %[ftmp9], %[ftmp9], %[ff_ph_22a3] \n\t"
+ "paddh %[ftmp8], %[ftmp9], %[ftmp2] \n\t"
+ "pmulhh %[ftmp10], %[ftmp2], %[ff_ph_4e7b] \n\t"
+ "paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t"
+
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp11] \n\t"
+ "paddh %[ftmp1], %[ftmp5], %[ftmp8] \n\t"
+ "paddh %[ftmp1], %[ftmp1], %[ff_pw_4] \n\t"
+ "psrah %[ftmp1], %[ftmp1], %[ftmp11] \n\t"
+ "paddh %[ftmp2], %[ftmp6], %[ftmp7] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ff_pw_4] \n\t"
+ "psrah %[ftmp2], %[ftmp2], %[ftmp11] \n\t"
+ "psubh %[ftmp3], %[ftmp6], %[ftmp7] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ff_pw_4] \n\t"
+ "psrah %[ftmp3], %[ftmp3], %[ftmp11] \n\t"
+ "psubh %[ftmp4], %[ftmp5], %[ftmp8] \n\t"
+ "paddh %[ftmp4], %[ftmp4], %[ff_pw_4] \n\t"
+ "psrah %[ftmp4], %[ftmp4], %[ftmp11] \n\t"
+
+ TRANSPOSE_4H(%[ftmp1], %[ftmp2], %[ftmp3], %[ftmp4],
+ %[ftmp5], %[ftmp6], %[ftmp7], %[ftmp8],
+ %[ftmp9], %[tmp0], %[ftmp0], %[ftmp10])
+
+ MMI_LWC1(%[ftmp5], %[dst0], 0x00)
+ MMI_LWC1(%[ftmp6], %[dst1], 0x00)
+ MMI_LWC1(%[ftmp7], %[dst2], 0x00)
+ MMI_LWC1(%[ftmp8], %[dst3], 0x00)
+
+ "punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t"
+
+ "paddh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
+ "paddh %[ftmp2], %[ftmp2], %[ftmp6] \n\t"
+ "paddh %[ftmp3], %[ftmp3], %[ftmp7] \n\t"
+ "paddh %[ftmp4], %[ftmp4], %[ftmp8] \n\t"
+
+ "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+
+ MMI_SWC1(%[ftmp1], %[dst0], 0x00)
+ MMI_SWC1(%[ftmp2], %[dst1], 0x00)
+ MMI_SWC1(%[ftmp3], %[dst2], 0x00)
+ MMI_SWC1(%[ftmp4], %[dst3], 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]),
+ RESTRICT_ASM_LOW32
+ RESTRICT_ASM_ALL64
+ [tmp0]"=&r"(tmp[0])
+ : [dst0]"r"(dst), [dst1]"r"(dst+stride),
+ [dst2]"r"(dst+2*stride), [dst3]"r"(dst+3*stride),
+ [block]"r"(block), [ff_pw_4]"f"(ff_pw_4),
+ [ff_ph_4e7b]"f"(ff_ph_4e7b), [ff_ph_22a3]"f"(ff_ph_22a3)
+ : "memory"
+ );
+#else
+ int i, t0, t1, t2, t3;
+ int16_t tmp[16];
+
+ for (i = 0; i < 4; i++) {
+ t0 = block[0 + i] + block[8 + i];
+ t1 = block[0 + i] - block[8 + i];
+ t2 = MUL_35468(block[4 + i]) - MUL_20091(block[12 + i]);
+ t3 = MUL_20091(block[4 + i]) + MUL_35468(block[12 + i]);
+ block[ 0 + i] = 0;
+ block[ 4 + i] = 0;
+ block[ 8 + i] = 0;
+ block[12 + i] = 0;
+
+ tmp[i * 4 + 0] = t0 + t3;
+ tmp[i * 4 + 1] = t1 + t2;
+ tmp[i * 4 + 2] = t1 - t2;
+ tmp[i * 4 + 3] = t0 - t3;
+ }
+
+ for (i = 0; i < 4; i++) {
+ t0 = tmp[0 + i] + tmp[8 + i];
+ t1 = tmp[0 + i] - tmp[8 + i];
+ t2 = MUL_35468(tmp[4 + i]) - MUL_20091(tmp[12 + i]);
+ t3 = MUL_20091(tmp[4 + i]) + MUL_35468(tmp[12 + i]);
+
+ dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3));
+ dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3));
+ dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3));
+ dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3));
+ dst += stride;
+ }
+#endif
+}
+
+void ff_vp8_idct_dc_add_mmi(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+#if 1
+ int dc = (block[0] + 4) >> 3;
+ double ftmp[6];
+ DECLARE_VAR_LOW32;
+
+ block[0] = 0;
+
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "mtc1 %[dc], %[ftmp5] \n\t"
+ MMI_LWC1(%[ftmp1], %[dst0], 0x00)
+ MMI_LWC1(%[ftmp2], %[dst1], 0x00)
+ MMI_LWC1(%[ftmp3], %[dst2], 0x00)
+ MMI_LWC1(%[ftmp4], %[dst3], 0x00)
+ "pshufh %[ftmp5], %[ftmp5], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+ "paddsh %[ftmp1], %[ftmp1], %[ftmp5] \n\t"
+ "paddsh %[ftmp2], %[ftmp2], %[ftmp5] \n\t"
+ "paddsh %[ftmp3], %[ftmp3], %[ftmp5] \n\t"
+ "paddsh %[ftmp4], %[ftmp4], %[ftmp5] \n\t"
+ "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t"
+ "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t"
+ "packushb %[ftmp3], %[ftmp3], %[ftmp0] \n\t"
+ "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t"
+ MMI_SWC1(%[ftmp1], %[dst0], 0x00)
+ MMI_SWC1(%[ftmp2], %[dst1], 0x00)
+ MMI_SWC1(%[ftmp3], %[dst2], 0x00)
+ MMI_SWC1(%[ftmp4], %[dst3], 0x00)
+ : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
+ [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]),
+ [ftmp4]"=&f"(ftmp[4]),
+ RESTRICT_ASM_LOW32
+ [ftmp5]"=&f"(ftmp[5])
+ : [dst0]"r"(dst), [dst1]"r"(dst+stride),
+ [dst2]"r"(dst+2*stride), [dst3]"r"(dst+3*stride),
+ [dc]"r"(dc)
+ : "memory"
+ );
+#else
+ int i, dc = (block[0] + 4) >> 3;
+
+ block[0] = 0;
+
+ for (i = 0; i < 4; i++) {
+ dst[0] = av_clip_uint8(dst[0] + dc);
+ dst[1] = av_clip_uint8(dst[1] + dc);
+ dst[2] = av_clip_uint8(dst[2] + dc);
+ dst[3] = av_clip_uint8(dst[3] + dc);
+ dst += stride;
+ }
+#endif
+}
+
+void ff_vp8_idct_dc_add4y_mmi(uint8_t *dst, int16_t block[4][16],
+ ptrdiff_t stride)
+{
+ ff_vp8_idct_dc_add_mmi(dst + 0, block[0], stride);
+ ff_vp8_idct_dc_add_mmi(dst + 4, block[1], stride);
+ ff_vp8_idct_dc_add_mmi(dst + 8, block[2], stride);
+ ff_vp8_idct_dc_add_mmi(dst + 12, block[3], stride);
+}
+
+void ff_vp8_idct_dc_add4uv_mmi(uint8_t *dst, int16_t block[4][16],
+ ptrdiff_t stride)
+{
+ ff_vp8_idct_dc_add_mmi(dst + stride * 0 + 0, block[0], stride);
+ ff_vp8_idct_dc_add_mmi(dst + stride * 0 + 4, block[1], stride);
+ ff_vp8_idct_dc_add_mmi(dst + stride * 4 + 0, block[2], stride);
+ ff_vp8_idct_dc_add_mmi(dst + stride * 4 + 4, block[3], stride);
+}
+
+// loop filter applied to edges between macroblocks
+void ff_vp8_v_loop_filter16_mmi(uint8_t *dst, ptrdiff_t stride, int flim_E,
+ int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_normal_limit(dst + i * 1, stride, flim_E, flim_I)) {
+ if (hev(dst + i * 1, stride, hev_thresh))
+ vp8_filter_common_is4tap(dst + i * 1, stride);
+ else
+ filter_mbedge(dst + i * 1, stride);
+ }
+}
+
+void ff_vp8_h_loop_filter16_mmi(uint8_t *dst, ptrdiff_t stride, int flim_E,
+ int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_normal_limit(dst + i * stride, 1, flim_E, flim_I)) {
+ if (hev(dst + i * stride, 1, hev_thresh))
+ vp8_filter_common_is4tap(dst + i * stride, 1);
+ else
+ filter_mbedge(dst + i * stride, 1);
+ }
+}
+
+void ff_vp8_v_loop_filter8uv_mmi(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh)
+{
+ vp8_v_loop_filter8_mmi(dstU, stride, flim_E, flim_I, hev_thresh);
+ vp8_v_loop_filter8_mmi(dstV, stride, flim_E, flim_I, hev_thresh);
+}
+
+void ff_vp8_h_loop_filter8uv_mmi(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh)
+{
+ vp8_h_loop_filter8_mmi(dstU, stride, flim_E, flim_I, hev_thresh);
+ vp8_h_loop_filter8_mmi(dstV, stride, flim_E, flim_I, hev_thresh);
+}
+
+// loop filter applied to inner macroblock edges
+void ff_vp8_v_loop_filter16_inner_mmi(uint8_t *dst, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_normal_limit(dst + i * 1, stride, flim_E, flim_I)) {
+ int hv = hev(dst + i * 1, stride, hev_thresh);
+ if (hv)
+ vp8_filter_common_is4tap(dst + i * 1, stride);
+ else
+ vp8_filter_common_isnot4tap(dst + i * 1, stride);
+ }
+}
+
+void ff_vp8_h_loop_filter16_inner_mmi(uint8_t *dst, ptrdiff_t stride,
+ int flim_E, int flim_I, int hev_thresh)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_normal_limit(dst + i * stride, 1, flim_E, flim_I)) {
+ int hv = hev(dst + i * stride, 1, hev_thresh);
+ if (hv)
+ vp8_filter_common_is4tap(dst + i * stride, 1);
+ else
+ vp8_filter_common_isnot4tap(dst + i * stride, 1);
+ }
+}
+
+void ff_vp8_v_loop_filter8uv_inner_mmi(uint8_t *dstU, uint8_t *dstV,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ vp8_v_loop_filter8_inner_mmi(dstU, stride, flim_E, flim_I, hev_thresh);
+ vp8_v_loop_filter8_inner_mmi(dstV, stride, flim_E, flim_I, hev_thresh);
+}
+
+void ff_vp8_h_loop_filter8uv_inner_mmi(uint8_t *dstU, uint8_t *dstV,
+ ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh)
+{
+ vp8_h_loop_filter8_inner_mmi(dstU, stride, flim_E, flim_I, hev_thresh);
+ vp8_h_loop_filter8_inner_mmi(dstV, stride, flim_E, flim_I, hev_thresh);
+}
+
+void ff_vp8_v_loop_filter_simple_mmi(uint8_t *dst, ptrdiff_t stride, int flim)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_simple_limit(dst + i, stride, flim))
+ vp8_filter_common_is4tap(dst + i, stride);
+}
+
+void ff_vp8_h_loop_filter_simple_mmi(uint8_t *dst, ptrdiff_t stride, int flim)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (vp8_simple_limit(dst + i * stride, 1, flim))
+ vp8_filter_common_is4tap(dst + i * stride, 1);
+}
+
+void ff_put_vp8_pixels16_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y)
+{
+#if 1
+ double ftmp[2];
+ uint64_t tmp[2];
+ mips_reg addr[2];
+ DECLARE_VAR_ALL64;
+
+ __asm__ volatile (
+ "1: \n\t"
+ PTR_ADDU "%[addr0], %[src], %[srcstride] \n\t"
+ MMI_ULDC1(%[ftmp0], %[src], 0x00)
+ "ldl %[tmp0], 0x0f(%[src]) \n\t"
+ "ldr %[tmp0], 0x08(%[src]) \n\t"
+ MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
+ "ldl %[tmp1], 0x0f(%[addr0]) \n\t"
+ "ldr %[tmp1], 0x08(%[addr0]) \n\t"
+ PTR_ADDU "%[addr1], %[dst], %[dststride] \n\t"
+ MMI_SDC1(%[ftmp0], %[dst], 0x00)
+ "sdl %[tmp0], 0x0f(%[dst]) \n\t"
+ "sdr %[tmp0], 0x08(%[dst]) \n\t"
+ "addiu %[h], %[h], -0x02 \n\t"
+ MMI_SDC1(%[ftmp1], %[addr1], 0x00)
+ PTR_ADDU "%[src], %[addr0], %[srcstride] \n\t"
+ "sdl %[tmp1], 0x0f(%[addr1]) \n\t"
+ "sdr %[tmp1], 0x08(%[addr1]) \n\t"
+ PTR_ADDU "%[dst], %[addr1], %[dststride] \n\t"
+ "bnez %[h], 1b \n\t"
+ : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]),
+ [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
+ RESTRICT_ASM_ALL64
+ [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [h]"+&r"(h)
+ : [dststride]"r"((mips_reg)dststride),
+ [srcstride]"r"((mips_reg)srcstride)
+ : "memory"
+ );
+#else
+ int i;
+
+ for (i = 0; i < h; i++, dst += dststride, src += srcstride)
+ memcpy(dst, src, 16);
+#endif
+}
+
+void ff_put_vp8_pixels8_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y)
+{
+#if 1
+ double ftmp[1];
+ uint64_t tmp[1];
+ mips_reg addr[2];
+ DECLARE_VAR_ALL64;
+
+ __asm__ volatile (
+ "1: \n\t"
+ PTR_ADDU "%[addr0], %[src], %[srcstride] \n\t"
+ MMI_ULDC1(%[ftmp0], %[src], 0x00)
+ "ldl %[tmp0], 0x07(%[addr0]) \n\t"
+ "ldr %[tmp0], 0x00(%[addr0]) \n\t"
+ PTR_ADDU "%[addr1], %[dst], %[dststride] \n\t"
+ MMI_SDC1(%[ftmp0], %[dst], 0x00)
+ "addiu %[h], %[h], -0x02 \n\t"
+ "sdl %[tmp0], 0x07(%[addr1]) \n\t"
+ "sdr %[tmp0], 0x00(%[addr1]) \n\t"
+ PTR_ADDU "%[src], %[addr0], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[addr1], %[dststride] \n\t"
+ "bnez %[h], 1b \n\t"
+ : [ftmp0]"=&f"(ftmp[0]), [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_ALL64
+ [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [h]"+&r"(h)
+ : [dststride]"r"((mips_reg)dststride),
+ [srcstride]"r"((mips_reg)srcstride)
+ : "memory"
+ );
+#else
+ int i;
+
+ for (i = 0; i < h; i++, dst += dststride, src += srcstride)
+ memcpy(dst, src, 8);
+#endif
+}
+
+void ff_put_vp8_pixels4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int x, int y)
+{
+#if 1
+ double ftmp[1];
+ uint64_t tmp[1];
+ mips_reg addr[2];
+ DECLARE_VAR_LOW32;
+
+ __asm__ volatile (
+ "1: \n\t"
+ PTR_ADDU "%[addr0], %[src], %[srcstride] \n\t"
+ MMI_LWC1(%[ftmp0], %[src], 0x00)
+ "lwl %[tmp0], 0x03(%[addr0]) \n\t"
+ "lwr %[tmp0], 0x00(%[addr0]) \n\t"
+ PTR_ADDU "%[addr1], %[dst], %[dststride] \n\t"
+ MMI_SWC1(%[ftmp0], %[dst], 0x00)
+ "addiu %[h], %[h], -0x02 \n\t"
+ "swl %[tmp0], 0x03(%[addr1]) \n\t"
+ "swr %[tmp0], 0x00(%[addr1]) \n\t"
+ PTR_ADDU "%[src], %[addr0], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[addr1], %[dststride] \n\t"
+ "bnez %[h], 1b \n\t"
+ : [ftmp0]"=&f"(ftmp[0]), [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_LOW32
+ [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [h]"+&r"(h)
+ : [dststride]"r"((mips_reg)dststride),
+ [srcstride]"r"((mips_reg)srcstride)
+ : "memory"
+ );
+#else
+ int i;
+
+ for (i = 0; i < h; i++, dst += dststride, src += srcstride)
+ memcpy(dst, src, 4);
+#endif
+}
+
+void ff_put_vp8_epel16_h4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src1, dst1;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[-1] + filter[3] * src[1] - filter[4] * src[2] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[ 0] + filter[3] * src[2] - filter[4] * src[3] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[ 1] + filter[3] * src[3] - filter[4] * src[4] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[ 2] + filter[3] * src[4] - filter[4] * src[5] + 64) >> 7];
+ dst[4] = cm[(filter[2] * src[4] - filter[1] * src[ 3] + filter[3] * src[5] - filter[4] * src[6] + 64) >> 7];
+ dst[5] = cm[(filter[2] * src[5] - filter[1] * src[ 4] + filter[3] * src[6] - filter[4] * src[7] + 64) >> 7];
+ dst[6] = cm[(filter[2] * src[6] - filter[1] * src[ 5] + filter[3] * src[7] - filter[4] * src[8] + 64) >> 7];
+ dst[7] = cm[(filter[2] * src[7] - filter[1] * src[ 6] + filter[3] * src[8] - filter[4] * src[9] + 64) >> 7];
+
+ dst[ 8] = cm[(filter[2] * src[ 8] - filter[1] * src[ 7] + filter[3] * src[ 9] - filter[4] * src[10] + 64) >> 7];
+ dst[ 9] = cm[(filter[2] * src[ 9] - filter[1] * src[ 8] + filter[3] * src[10] - filter[4] * src[11] + 64) >> 7];
+ dst[10] = cm[(filter[2] * src[10] - filter[1] * src[ 9] + filter[3] * src[11] - filter[4] * src[12] + 64) >> 7];
+ dst[11] = cm[(filter[2] * src[11] - filter[1] * src[10] + filter[3] * src[12] - filter[4] * src[13] + 64) >> 7];
+ dst[12] = cm[(filter[2] * src[12] - filter[1] * src[11] + filter[3] * src[13] - filter[4] * src[14] + 64) >> 7];
+ dst[13] = cm[(filter[2] * src[13] - filter[1] * src[12] + filter[3] * src[14] - filter[4] * src[15] + 64) >> 7];
+ dst[14] = cm[(filter[2] * src[14] - filter[1] * src[13] + filter[3] * src[15] - filter[4] * src[16] + 64) >> 7];
+ dst[15] = cm[(filter[2] * src[15] - filter[1] * src[14] + filter[3] * src[16] - filter[4] * src[17] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_EPEL8_H4_MMI(%[src], %[dst])
+ PTR_ADDIU "%[src1], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst1], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_EPEL8_H4_MMI(%[src1], %[dst1])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [dst1]"=&r"(dst1), [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_4TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[-1] + filter[3] * src[1] - filter[4] * src[2] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[ 0] + filter[3] * src[2] - filter[4] * src[3] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[ 1] + filter[3] * src[3] - filter[4] * src[4] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[ 2] + filter[3] * src[4] - filter[4] * src[5] + 64) >> 7];
+ dst[4] = cm[(filter[2] * src[4] - filter[1] * src[ 3] + filter[3] * src[5] - filter[4] * src[6] + 64) >> 7];
+ dst[5] = cm[(filter[2] * src[5] - filter[1] * src[ 4] + filter[3] * src[6] - filter[4] * src[7] + 64) >> 7];
+ dst[6] = cm[(filter[2] * src[6] - filter[1] * src[ 5] + filter[3] * src[7] - filter[4] * src[8] + 64) >> 7];
+ dst[7] = cm[(filter[2] * src[7] - filter[1] * src[ 6] + filter[3] * src[8] - filter[4] * src[9] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL8_H4_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_4TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[6];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[-1] + filter[3] * src[1] - filter[4] * src[2] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[ 0] + filter[3] * src[2] - filter[4] * src[3] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[ 1] + filter[3] * src[3] - filter[4] * src[4] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[ 2] + filter[3] * src[4] - filter[4] * src[5] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL4_H4_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_4TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_h6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src1, dst1;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[ 0] = cm[(filter[2]*src[ 0] - filter[1]*src[-1] + filter[0]*src[-2] + filter[3]*src[ 1] - filter[4]*src[ 2] + filter[5]*src[ 3] + 64) >> 7];
+ dst[ 1] = cm[(filter[2]*src[ 1] - filter[1]*src[ 0] + filter[0]*src[-1] + filter[3]*src[ 2] - filter[4]*src[ 3] + filter[5]*src[ 4] + 64) >> 7];
+ dst[ 2] = cm[(filter[2]*src[ 2] - filter[1]*src[ 1] + filter[0]*src[ 0] + filter[3]*src[ 3] - filter[4]*src[ 4] + filter[5]*src[ 5] + 64) >> 7];
+ dst[ 3] = cm[(filter[2]*src[ 3] - filter[1]*src[ 2] + filter[0]*src[ 1] + filter[3]*src[ 4] - filter[4]*src[ 5] + filter[5]*src[ 6] + 64) >> 7];
+ dst[ 4] = cm[(filter[2]*src[ 4] - filter[1]*src[ 3] + filter[0]*src[ 2] + filter[3]*src[ 5] - filter[4]*src[ 6] + filter[5]*src[ 7] + 64) >> 7];
+ dst[ 5] = cm[(filter[2]*src[ 5] - filter[1]*src[ 4] + filter[0]*src[ 3] + filter[3]*src[ 6] - filter[4]*src[ 7] + filter[5]*src[ 8] + 64) >> 7];
+ dst[ 6] = cm[(filter[2]*src[ 6] - filter[1]*src[ 5] + filter[0]*src[ 4] + filter[3]*src[ 7] - filter[4]*src[ 8] + filter[5]*src[ 9] + 64) >> 7];
+ dst[ 7] = cm[(filter[2]*src[ 7] - filter[1]*src[ 6] + filter[0]*src[ 5] + filter[3]*src[ 8] - filter[4]*src[ 9] + filter[5]*src[10] + 64) >> 7];
+
+ dst[ 8] = cm[(filter[2]*src[ 8] - filter[1]*src[ 7] + filter[0]*src[ 6] + filter[3]*src[ 9] - filter[4]*src[10] + filter[5]*src[11] + 64) >> 7];
+ dst[ 9] = cm[(filter[2]*src[ 9] - filter[1]*src[ 8] + filter[0]*src[ 7] + filter[3]*src[10] - filter[4]*src[11] + filter[5]*src[12] + 64) >> 7];
+ dst[10] = cm[(filter[2]*src[10] - filter[1]*src[ 9] + filter[0]*src[ 8] + filter[3]*src[11] - filter[4]*src[12] + filter[5]*src[13] + 64) >> 7];
+ dst[11] = cm[(filter[2]*src[11] - filter[1]*src[10] + filter[0]*src[ 9] + filter[3]*src[12] - filter[4]*src[13] + filter[5]*src[14] + 64) >> 7];
+ dst[12] = cm[(filter[2]*src[12] - filter[1]*src[11] + filter[0]*src[10] + filter[3]*src[13] - filter[4]*src[14] + filter[5]*src[15] + 64) >> 7];
+ dst[13] = cm[(filter[2]*src[13] - filter[1]*src[12] + filter[0]*src[11] + filter[3]*src[14] - filter[4]*src[15] + filter[5]*src[16] + 64) >> 7];
+ dst[14] = cm[(filter[2]*src[14] - filter[1]*src[13] + filter[0]*src[12] + filter[3]*src[15] - filter[4]*src[16] + filter[5]*src[17] + 64) >> 7];
+ dst[15] = cm[(filter[2]*src[15] - filter[1]*src[14] + filter[0]*src[13] + filter[3]*src[16] - filter[4]*src[17] + filter[5]*src[18] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_EPEL8_H6_MMI(%[src], %[dst])
+ PTR_ADDIU "%[src1], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst1], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_EPEL8_H6_MMI(%[src1], %[dst1])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [dst1]"=&r"(dst1), [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_6TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2]*src[0] - filter[1]*src[-1] + filter[0]*src[-2] + filter[3]*src[1] - filter[4]*src[2] + filter[5]*src[ 3] + 64) >> 7];
+ dst[1] = cm[(filter[2]*src[1] - filter[1]*src[ 0] + filter[0]*src[-1] + filter[3]*src[2] - filter[4]*src[3] + filter[5]*src[ 4] + 64) >> 7];
+ dst[2] = cm[(filter[2]*src[2] - filter[1]*src[ 1] + filter[0]*src[ 0] + filter[3]*src[3] - filter[4]*src[4] + filter[5]*src[ 5] + 64) >> 7];
+ dst[3] = cm[(filter[2]*src[3] - filter[1]*src[ 2] + filter[0]*src[ 1] + filter[3]*src[4] - filter[4]*src[5] + filter[5]*src[ 6] + 64) >> 7];
+ dst[4] = cm[(filter[2]*src[4] - filter[1]*src[ 3] + filter[0]*src[ 2] + filter[3]*src[5] - filter[4]*src[6] + filter[5]*src[ 7] + 64) >> 7];
+ dst[5] = cm[(filter[2]*src[5] - filter[1]*src[ 4] + filter[0]*src[ 3] + filter[3]*src[6] - filter[4]*src[7] + filter[5]*src[ 8] + 64) >> 7];
+ dst[6] = cm[(filter[2]*src[6] - filter[1]*src[ 5] + filter[0]*src[ 4] + filter[3]*src[7] - filter[4]*src[8] + filter[5]*src[ 9] + 64) >> 7];
+ dst[7] = cm[(filter[2]*src[7] - filter[1]*src[ 6] + filter[0]*src[ 5] + filter[3]*src[8] - filter[4]*src[9] + filter[5]*src[10] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL8_H6_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_6TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[mx - 1];
+ double ftmp[6];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+
+ /*
+ dst[0] = cm[(filter[2]*src[0] - filter[1]*src[-1] + filter[0]*src[-2] + filter[3]*src[1] - filter[4]*src[2] + filter[5]*src[ 3] + 64) >> 7];
+ dst[1] = cm[(filter[2]*src[1] - filter[1]*src[ 0] + filter[0]*src[-1] + filter[3]*src[2] - filter[4]*src[3] + filter[5]*src[ 4] + 64) >> 7];
+ dst[2] = cm[(filter[2]*src[2] - filter[1]*src[ 1] + filter[0]*src[ 0] + filter[3]*src[3] - filter[4]*src[4] + filter[5]*src[ 5] + 64) >> 7];
+ dst[3] = cm[(filter[2]*src[3] - filter[1]*src[ 2] + filter[0]*src[ 1] + filter[3]*src[4] - filter[4]*src[5] + filter[5]*src[ 6] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL4_H6_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_6TAP(src, filter, 1);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src0, src1, dst0;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[ -srcstride] + filter[3] * src[ srcstride] - filter[4] * src[ 2*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[1-srcstride] + filter[3] * src[1+srcstride] - filter[4] * src[1+2*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[2-srcstride] + filter[3] * src[2+srcstride] - filter[4] * src[2+2*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[3-srcstride] + filter[3] * src[3+srcstride] - filter[4] * src[3+2*srcstride] + 64) >> 7];
+ dst[4] = cm[(filter[2] * src[4] - filter[1] * src[4-srcstride] + filter[3] * src[4+srcstride] - filter[4] * src[4+2*srcstride] + 64) >> 7];
+ dst[5] = cm[(filter[2] * src[5] - filter[1] * src[5-srcstride] + filter[3] * src[5+srcstride] - filter[4] * src[5+2*srcstride] + 64) >> 7];
+ dst[6] = cm[(filter[2] * src[6] - filter[1] * src[6-srcstride] + filter[3] * src[6+srcstride] - filter[4] * src[6+2*srcstride] + 64) >> 7];
+ dst[7] = cm[(filter[2] * src[7] - filter[1] * src[7-srcstride] + filter[3] * src[7+srcstride] - filter[4] * src[7+2*srcstride] + 64) >> 7];
+
+ dst[ 8] = cm[(filter[2] * src[ 8] - filter[1] * src[ 8-srcstride] + filter[3] * src[ 8+srcstride] - filter[4] * src[ 8+2*srcstride] + 64) >> 7];
+ dst[ 9] = cm[(filter[2] * src[ 9] - filter[1] * src[ 9-srcstride] + filter[3] * src[ 9+srcstride] - filter[4] * src[ 9+2*srcstride] + 64) >> 7];
+ dst[10] = cm[(filter[2] * src[10] - filter[1] * src[10-srcstride] + filter[3] * src[10+srcstride] - filter[4] * src[10+2*srcstride] + 64) >> 7];
+ dst[11] = cm[(filter[2] * src[11] - filter[1] * src[11-srcstride] + filter[3] * src[11+srcstride] - filter[4] * src[11+2*srcstride] + 64) >> 7];
+ dst[12] = cm[(filter[2] * src[12] - filter[1] * src[12-srcstride] + filter[3] * src[12+srcstride] - filter[4] * src[12+2*srcstride] + 64) >> 7];
+ dst[13] = cm[(filter[2] * src[13] - filter[1] * src[13-srcstride] + filter[3] * src[13+srcstride] - filter[4] * src[13+2*srcstride] + 64) >> 7];
+ dst[14] = cm[(filter[2] * src[14] - filter[1] * src[14-srcstride] + filter[3] * src[14+srcstride] - filter[4] * src[14+2*srcstride] + 64) >> 7];
+ dst[15] = cm[(filter[2] * src[15] - filter[1] * src[15-srcstride] + filter[3] * src[15+srcstride] - filter[4] * src[15+2*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_EPEL8_V4_MMI(%[src], %[src1], %[dst], %[srcstride])
+ PTR_ADDIU "%[src0], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst0], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_EPEL8_V4_MMI(%[src0], %[src1], %[dst], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [src0]"=&r"(src0), [dst0]"=&r"(dst0),
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_4TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[ -srcstride] + filter[3] * src[ srcstride] - filter[4] * src[ 2*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[1-srcstride] + filter[3] * src[1+srcstride] - filter[4] * src[1+2*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[2-srcstride] + filter[3] * src[2+srcstride] - filter[4] * src[2+2*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[3-srcstride] + filter[3] * src[3+srcstride] - filter[4] * src[3+2*srcstride] + 64) >> 7];
+ dst[4] = cm[(filter[2] * src[4] - filter[1] * src[4-srcstride] + filter[3] * src[4+srcstride] - filter[4] * src[4+2*srcstride] + 64) >> 7];
+ dst[5] = cm[(filter[2] * src[5] - filter[1] * src[5-srcstride] + filter[3] * src[5+srcstride] - filter[4] * src[5+2*srcstride] + 64) >> 7];
+ dst[6] = cm[(filter[2] * src[6] - filter[1] * src[6-srcstride] + filter[3] * src[6+srcstride] - filter[4] * src[6+2*srcstride] + 64) >> 7];
+ dst[7] = cm[(filter[2] * src[7] - filter[1] * src[7-srcstride] + filter[3] * src[7+srcstride] - filter[4] * src[7+2*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL8_V4_MMI(%[src], %[src1], %[dst], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_4TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[6];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_LOW32;
+
+ /*
+ dst[0] = cm[(filter[2] * src[0] - filter[1] * src[ -srcstride] + filter[3] * src[ srcstride] - filter[4] * src[ 2*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2] * src[1] - filter[1] * src[1-srcstride] + filter[3] * src[1+srcstride] - filter[4] * src[1+2*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2] * src[2] - filter[1] * src[2-srcstride] + filter[3] * src[2+srcstride] - filter[4] * src[2+2*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2] * src[3] - filter[1] * src[3-srcstride] + filter[3] * src[3+srcstride] - filter[4] * src[3+2*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL4_V4_MMI(%[src], %[src1], %[dst], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter1]"f"(filter[1]), [filter2]"f"(filter[2]),
+ [filter3]"f"(filter[3]), [filter4]"f"(filter[4])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_4TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src0, src1, dst0;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2]*src[0] - filter[1]*src[0-srcstride] + filter[0]*src[0-2*srcstride] + filter[3]*src[0+srcstride] - filter[4]*src[0+2*srcstride] + filter[5]*src[0+3*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2]*src[1] - filter[1]*src[1-srcstride] + filter[0]*src[1-2*srcstride] + filter[3]*src[1+srcstride] - filter[4]*src[1+2*srcstride] + filter[5]*src[1+3*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2]*src[2] - filter[1]*src[2-srcstride] + filter[0]*src[2-2*srcstride] + filter[3]*src[2+srcstride] - filter[4]*src[2+2*srcstride] + filter[5]*src[2+3*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2]*src[3] - filter[1]*src[3-srcstride] + filter[0]*src[3-2*srcstride] + filter[3]*src[3+srcstride] - filter[4]*src[3+2*srcstride] + filter[5]*src[3+3*srcstride] + 64) >> 7];
+ dst[4] = cm[(filter[2]*src[4] - filter[1]*src[4-srcstride] + filter[0]*src[4-2*srcstride] + filter[3]*src[4+srcstride] - filter[4]*src[4+2*srcstride] + filter[5]*src[4+3*srcstride] + 64) >> 7];
+ dst[5] = cm[(filter[2]*src[5] - filter[1]*src[5-srcstride] + filter[0]*src[5-2*srcstride] + filter[3]*src[5+srcstride] - filter[4]*src[5+2*srcstride] + filter[5]*src[5+3*srcstride] + 64) >> 7];
+ dst[6] = cm[(filter[2]*src[6] - filter[1]*src[6-srcstride] + filter[0]*src[6-2*srcstride] + filter[3]*src[6+srcstride] - filter[4]*src[6+2*srcstride] + filter[5]*src[6+3*srcstride] + 64) >> 7];
+ dst[7] = cm[(filter[2]*src[7] - filter[1]*src[7-srcstride] + filter[0]*src[7-2*srcstride] + filter[3]*src[7+srcstride] - filter[4]*src[7+2*srcstride] + filter[5]*src[7+3*srcstride] + 64) >> 7];
+
+ dst[ 8] = cm[(filter[2]*src[ 8] - filter[1]*src[ 8-srcstride] + filter[0]*src[ 8-2*srcstride] + filter[3]*src[ 8+srcstride] - filter[4]*src[ 8+2*srcstride] + filter[5]*src[ 8+3*srcstride] + 64) >> 7];
+ dst[ 9] = cm[(filter[2]*src[ 9] - filter[1]*src[ 9-srcstride] + filter[0]*src[ 9-2*srcstride] + filter[3]*src[ 9+srcstride] - filter[4]*src[ 9+2*srcstride] + filter[5]*src[ 9+3*srcstride] + 64) >> 7];
+ dst[10] = cm[(filter[2]*src[10] - filter[1]*src[10-srcstride] + filter[0]*src[10-2*srcstride] + filter[3]*src[10+srcstride] - filter[4]*src[10+2*srcstride] + filter[5]*src[10+3*srcstride] + 64) >> 7];
+ dst[11] = cm[(filter[2]*src[11] - filter[1]*src[11-srcstride] + filter[0]*src[11-2*srcstride] + filter[3]*src[11+srcstride] - filter[4]*src[11+2*srcstride] + filter[5]*src[11+3*srcstride] + 64) >> 7];
+ dst[12] = cm[(filter[2]*src[12] - filter[1]*src[12-srcstride] + filter[0]*src[12-2*srcstride] + filter[3]*src[12+srcstride] - filter[4]*src[12+2*srcstride] + filter[5]*src[12+3*srcstride] + 64) >> 7];
+ dst[13] = cm[(filter[2]*src[13] - filter[1]*src[13-srcstride] + filter[0]*src[13-2*srcstride] + filter[3]*src[13+srcstride] - filter[4]*src[13+2*srcstride] + filter[5]*src[13+3*srcstride] + 64) >> 7];
+ dst[14] = cm[(filter[2]*src[14] - filter[1]*src[14-srcstride] + filter[0]*src[14-2*srcstride] + filter[3]*src[14+srcstride] - filter[4]*src[14+2*srcstride] + filter[5]*src[14+3*srcstride] + 64) >> 7];
+ dst[15] = cm[(filter[2]*src[15] - filter[1]*src[15-srcstride] + filter[0]*src[15-2*srcstride] + filter[3]*src[15+srcstride] - filter[4]*src[15+2*srcstride] + filter[5]*src[15+3*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_EPEL8_V6_MMI(%[src], %[src1], %[dst], %[srcstride])
+ PTR_ADDIU "%[src0], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst0], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_EPEL8_V6_MMI(%[src0], %[src1], %[dst0], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [src0]"=&r"(src0), [dst0]"=&r"(dst0),
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_6TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[9];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = cm[(filter[2]*src[0] - filter[1]*src[0-srcstride] + filter[0]*src[0-2*srcstride] + filter[3]*src[0+srcstride] - filter[4]*src[0+2*srcstride] + filter[5]*src[0+3*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2]*src[1] - filter[1]*src[1-srcstride] + filter[0]*src[1-2*srcstride] + filter[3]*src[1+srcstride] - filter[4]*src[1+2*srcstride] + filter[5]*src[1+3*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2]*src[2] - filter[1]*src[2-srcstride] + filter[0]*src[2-2*srcstride] + filter[3]*src[2+srcstride] - filter[4]*src[2+2*srcstride] + filter[5]*src[2+3*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2]*src[3] - filter[1]*src[3-srcstride] + filter[0]*src[3-2*srcstride] + filter[3]*src[3+srcstride] - filter[4]*src[3+2*srcstride] + filter[5]*src[3+3*srcstride] + 64) >> 7];
+ dst[4] = cm[(filter[2]*src[4] - filter[1]*src[4-srcstride] + filter[0]*src[4-2*srcstride] + filter[3]*src[4+srcstride] - filter[4]*src[4+2*srcstride] + filter[5]*src[4+3*srcstride] + 64) >> 7];
+ dst[5] = cm[(filter[2]*src[5] - filter[1]*src[5-srcstride] + filter[0]*src[5-2*srcstride] + filter[3]*src[5+srcstride] - filter[4]*src[5+2*srcstride] + filter[5]*src[5+3*srcstride] + 64) >> 7];
+ dst[6] = cm[(filter[2]*src[6] - filter[1]*src[6-srcstride] + filter[0]*src[6-2*srcstride] + filter[3]*src[6+srcstride] - filter[4]*src[6+2*srcstride] + filter[5]*src[6+3*srcstride] + 64) >> 7];
+ dst[7] = cm[(filter[2]*src[7] - filter[1]*src[7-srcstride] + filter[0]*src[7-2*srcstride] + filter[3]*src[7+srcstride] - filter[4]*src[7+2*srcstride] + filter[5]*src[7+3*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL8_V6_MMI(%[src], %[src1], %[dst], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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]),
+ RESTRICT_ASM_ALL64
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_6TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ const uint64_t *filter = fourtap_subpel_filters[my - 1];
+ double ftmp[6];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_LOW32;
+
+ /*
+ dst[0] = cm[(filter[2]*src[0] - filter[1]*src[0-srcstride] + filter[0]*src[0-2*srcstride] + filter[3]*src[0+srcstride] - filter[4]*src[0+2*srcstride] + filter[5]*src[0+3*srcstride] + 64) >> 7];
+ dst[1] = cm[(filter[2]*src[1] - filter[1]*src[1-srcstride] + filter[0]*src[1-2*srcstride] + filter[3]*src[1+srcstride] - filter[4]*src[1+2*srcstride] + filter[5]*src[1+3*srcstride] + 64) >> 7];
+ dst[2] = cm[(filter[2]*src[2] - filter[1]*src[2-srcstride] + filter[0]*src[2-2*srcstride] + filter[3]*src[2+srcstride] - filter[4]*src[2+2*srcstride] + filter[5]*src[2+3*srcstride] + 64) >> 7];
+ dst[3] = cm[(filter[2]*src[3] - filter[1]*src[3-srcstride] + filter[0]*src[3-2*srcstride] + filter[3]*src[3+srcstride] - filter[4]*src[3+2*srcstride] + filter[5]*src[3+3*srcstride] + 64) >> 7];
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x07 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_EPEL4_V6_MMI(%[src], %[src1], %[dst], %[srcstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[srcstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dststride] \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
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src)
+ : [ff_pw_64]"f"(ff_pw_64),
+ [srcstride]"r"((mips_reg)srcstride),
+ [dststride]"r"((mips_reg)dststride),
+ [filter0]"f"(filter[0]), [filter1]"f"(filter[1]),
+ [filter2]"f"(filter[2]), [filter3]"f"(filter[3]),
+ [filter4]"f"(filter[4]), [filter5]"f"(filter[5])
+ : "memory"
+ );
+#else
+ const uint8_t *filter = subpel_filters[my - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_6TAP(src, filter, srcstride);
+ dst += dststride;
+ src += srcstride;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[560]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel16_h4_mmi(tmp, 16, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 16;
+ ff_put_vp8_epel16_v4_mmi(dst, dststride, tmp, 16, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[560];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 16; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 16;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 16;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 16);
+ dst += dststride;
+ tmp += 16;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[152]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel8_h4_mmi(tmp, 8, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 8;
+ ff_put_vp8_epel8_v4_mmi(dst, dststride, tmp, 8, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[152];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 8; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 8;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 8;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 8);
+ dst += dststride;
+ tmp += 8;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h4v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(4, uint8_t, tmp_array[44]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel4_h4_mmi(tmp, 4, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 4;
+ ff_put_vp8_epel4_v4_mmi(dst, dststride, tmp, 4, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[44];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 4; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 4;
+ src += srcstride;
+ }
+ tmp = tmp_array + 4;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 4);
+ dst += dststride;
+ tmp += 4;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[592]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel16_h4_mmi(tmp, 16, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 32;
+ ff_put_vp8_epel16_v6_mmi(dst, dststride, tmp, 16, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[592];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 16; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 16;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 32;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 16);
+ dst += dststride;
+ tmp += 16;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[168]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel8_h4_mmi(tmp, 8, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 16;
+ ff_put_vp8_epel8_v6_mmi(dst, dststride, tmp, 8, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[168];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 8; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 8;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 16;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 8);
+ dst += dststride;
+ tmp += 8;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h4v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(4, uint8_t, tmp_array[52]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel4_h4_mmi(tmp, 4, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 8;
+ ff_put_vp8_epel4_v6_mmi(dst, dststride, tmp, 4, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[52];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 4; x++)
+ tmp[x] = FILTER_4TAP(src, filter, 1);
+ tmp += 4;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 8;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 4);
+ dst += dststride;
+ tmp += 4;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[560]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel16_h6_mmi(tmp, 16, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 16;
+ ff_put_vp8_epel16_v4_mmi(dst, dststride, tmp, 16, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[560];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 16; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 16;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 16;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 16);
+ dst += dststride;
+ tmp += 16;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[152]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel8_h6_mmi(tmp, 8, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 8;
+ ff_put_vp8_epel8_v4_mmi(dst, dststride, tmp, 8, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[152];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 8; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 8;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 8;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 8);
+ dst += dststride;
+ tmp += 8;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h6v4_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(4, uint8_t, tmp_array[44]);
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+ ff_put_vp8_epel4_h6_mmi(tmp, 4, src, srcstride, h + 3, mx, my);
+ tmp = tmp_array + 4;
+ ff_put_vp8_epel4_v4_mmi(dst, dststride, tmp, 4, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[44];
+ uint8_t *tmp = tmp_array;
+
+ src -= srcstride;
+
+ for (y = 0; y < h + 3; y++) {
+ for (x = 0; x < 4; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 4;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 4;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_4TAP(tmp, filter, 4);
+ dst += dststride;
+ tmp += 4;
+ }
+#endif
+}
+
+void ff_put_vp8_epel16_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[592]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel16_h6_mmi(tmp, 16, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 32;
+ ff_put_vp8_epel16_v6_mmi(dst, dststride, tmp, 16, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[592];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 16; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 16;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 32;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 16);
+ dst += dststride;
+ tmp += 16;
+ }
+#endif
+}
+
+void ff_put_vp8_epel8_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[168]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel8_h6_mmi(tmp, 8, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 16;
+ ff_put_vp8_epel8_v6_mmi(dst, dststride, tmp, 8, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[168];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 8; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 8;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 16;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 8);
+ dst += dststride;
+ tmp += 8;
+ }
+#endif
+}
+
+void ff_put_vp8_epel4_h6v6_mmi(uint8_t *dst, ptrdiff_t dststride, uint8_t *src,
+ ptrdiff_t srcstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(4, uint8_t, tmp_array[52]);
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+ ff_put_vp8_epel4_h6_mmi(tmp, 4, src, srcstride, h + 5, mx, my);
+ tmp = tmp_array + 8;
+ ff_put_vp8_epel4_v6_mmi(dst, dststride, tmp, 4, h, mx, my);
+#else
+ const uint8_t *filter = subpel_filters[mx - 1];
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int x, y;
+ uint8_t tmp_array[52];
+ uint8_t *tmp = tmp_array;
+
+ src -= 2 * srcstride;
+
+ for (y = 0; y < h + 5; y++) {
+ for (x = 0; x < 4; x++)
+ tmp[x] = FILTER_6TAP(src, filter, 1);
+ tmp += 4;
+ src += srcstride;
+ }
+
+ tmp = tmp_array + 8;
+ filter = subpel_filters[my - 1];
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = FILTER_6TAP(tmp, filter, 4);
+ dst += dststride;
+ tmp += 4;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear16_h_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int a = 8 - mx, b = mx;
+ double ftmp[7];
+ uint32_t tmp[1];
+ mips_reg dst0, src0;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (a * src[0] + b * src[1] + 4) >> 3;
+ dst[1] = (a * src[1] + b * src[2] + 4) >> 3;
+ dst[2] = (a * src[2] + b * src[3] + 4) >> 3;
+ dst[3] = (a * src[3] + b * src[4] + 4) >> 3;
+ dst[4] = (a * src[4] + b * src[5] + 4) >> 3;
+ dst[5] = (a * src[5] + b * src[6] + 4) >> 3;
+ dst[6] = (a * src[6] + b * src[7] + 4) >> 3;
+ dst[7] = (a * src[7] + b * src[8] + 4) >> 3;
+
+ dst[ 8] = (a * src[ 8] + b * src[ 9] + 4) >> 3;
+ dst[ 9] = (a * src[ 9] + b * src[10] + 4) >> 3;
+ dst[10] = (a * src[10] + b * src[11] + 4) >> 3;
+ dst[11] = (a * src[11] + b * src[12] + 4) >> 3;
+ dst[12] = (a * src[12] + b * src[13] + 4) >> 3;
+ dst[13] = (a * src[13] + b * src[14] + 4) >> 3;
+ dst[14] = (a * src[14] + b * src[15] + 4) >> 3;
+ dst[15] = (a * src[15] + b * src[16] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[a], %[a], %[ftmp0] \n\t"
+ "pshufh %[b], %[b], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_BILINEAR8_H_MMI(%[src], %[dst])
+ PTR_ADDIU "%[src0], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst0], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_BILINEAR8_H_MMI(%[src0], %[dst0])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_ALL64
+ [dst0]"=&r"(dst0), [src0]"=&r"(src0),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [a]"+&f"(a), [b]"+&f"(b)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int a = 8 - mx, b = mx;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear16_v_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int c = 8 - my, d = my;
+ double ftmp[7];
+ uint32_t tmp[1];
+ mips_reg src0, src1, dst0;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (c * src[0] + d * src[ sstride] + 4) >> 3;
+ dst[1] = (c * src[1] + d * src[1 + sstride] + 4) >> 3;
+ dst[2] = (c * src[2] + d * src[2 + sstride] + 4) >> 3;
+ dst[3] = (c * src[3] + d * src[3 + sstride] + 4) >> 3;
+ dst[4] = (c * src[4] + d * src[4 + sstride] + 4) >> 3;
+ dst[5] = (c * src[5] + d * src[5 + sstride] + 4) >> 3;
+ dst[6] = (c * src[6] + d * src[6 + sstride] + 4) >> 3;
+ dst[7] = (c * src[7] + d * src[7 + sstride] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[c], %[c], %[ftmp0] \n\t"
+ "pshufh %[d], %[d], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ // 0 - 7
+ PUT_VP8_BILINEAR8_V_MMI(%[src], %[src1], %[dst], %[sstride])
+ PTR_ADDIU "%[src0], %[src], 0x08 \n\t"
+ PTR_ADDIU "%[dst0], %[dst], 0x08 \n\t"
+ // 8 - 15
+ PUT_VP8_BILINEAR8_V_MMI(%[src0], %[src1], %[dst0], %[sstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_ALL64
+ [src0]"=&r"(src0), [dst0]"=&r"(dst0),
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [c]"+&f"(c), [d]"+&f"(d)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int c = 8 - my, d = my;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear16_hv_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[528]);
+ uint8_t *tmp = tmp_array;
+
+ ff_put_vp8_bilinear16_h_mmi(tmp, 16, src, sstride, h + 1, mx, my);
+ ff_put_vp8_bilinear16_v_mmi(dst, dstride, tmp, 16, h, mx, my);
+#else
+ int a = 8 - mx, b = mx;
+ int c = 8 - my, d = my;
+ int x, y;
+ uint8_t tmp_array[528];
+ uint8_t *tmp = tmp_array;
+
+ for (y = 0; y < h + 1; y++) {
+ for (x = 0; x < 16; x++)
+ tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ tmp += 16;
+ src += sstride;
+ }
+
+ tmp = tmp_array;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 16; x++)
+ dst[x] = (c * tmp[x] + d * tmp[x + 16] + 4) >> 3;
+ dst += dstride;
+ tmp += 16;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear8_h_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int a = 8 - mx, b = mx;
+ double ftmp[7];
+ uint32_t tmp[1];
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (a * src[0] + b * src[1] + 4) >> 3;
+ dst[1] = (a * src[1] + b * src[2] + 4) >> 3;
+ dst[2] = (a * src[2] + b * src[3] + 4) >> 3;
+ dst[3] = (a * src[3] + b * src[4] + 4) >> 3;
+ dst[4] = (a * src[4] + b * src[5] + 4) >> 3;
+ dst[5] = (a * src[5] + b * src[6] + 4) >> 3;
+ dst[6] = (a * src[6] + b * src[7] + 4) >> 3;
+ dst[7] = (a * src[7] + b * src[8] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[a], %[a], %[ftmp0] \n\t"
+ "pshufh %[b], %[b], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_BILINEAR8_H_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_ALL64
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [a]"+&f"(a), [b]"+&f"(b)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int a = 8 - mx, b = mx;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear8_v_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int c = 8 - my, d = my;
+ double ftmp[7];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (c * src[0] + d * src[ sstride] + 4) >> 3;
+ dst[1] = (c * src[1] + d * src[1 + sstride] + 4) >> 3;
+ dst[2] = (c * src[2] + d * src[2 + sstride] + 4) >> 3;
+ dst[3] = (c * src[3] + d * src[3 + sstride] + 4) >> 3;
+ dst[4] = (c * src[4] + d * src[4 + sstride] + 4) >> 3;
+ dst[5] = (c * src[5] + d * src[5 + sstride] + 4) >> 3;
+ dst[6] = (c * src[6] + d * src[6 + sstride] + 4) >> 3;
+ dst[7] = (c * src[7] + d * src[7 + sstride] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[c], %[c], %[ftmp0] \n\t"
+ "pshufh %[d], %[d], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_BILINEAR8_V_MMI(%[src], %[src1], %[dst], %[sstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_ALL64
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [c]"+&f"(c), [d]"+&f"(d)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int c = 8 - my, d = my;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear8_hv_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(8, uint8_t, tmp_array[136]);
+ uint8_t *tmp = tmp_array;
+
+ ff_put_vp8_bilinear8_h_mmi(tmp, 8, src, sstride, h + 1, mx, my);
+ ff_put_vp8_bilinear8_v_mmi(dst, dstride, tmp, 8, h, mx, my);
+#else
+ int a = 8 - mx, b = mx;
+ int c = 8 - my, d = my;
+ int x, y;
+ uint8_t tmp_array[136];
+ uint8_t *tmp = tmp_array;
+
+ for (y = 0; y < h + 1; y++) {
+ for (x = 0; x < 8; x++)
+ tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ tmp += 8;
+ src += sstride;
+ }
+
+ tmp = tmp_array;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 8; x++)
+ dst[x] = (c * tmp[x] + d * tmp[x + 8] + 4) >> 3;
+ dst += dstride;
+ tmp += 8;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear4_h_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int a = 8 - mx, b = mx;
+ double ftmp[5];
+ uint32_t tmp[1];
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (a * src[0] + b * src[1] + 4) >> 3;
+ dst[1] = (a * src[1] + b * src[2] + 4) >> 3;
+ dst[2] = (a * src[2] + b * src[3] + 4) >> 3;
+ dst[3] = (a * src[3] + b * src[4] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[a], %[a], %[ftmp0] \n\t"
+ "pshufh %[b], %[b], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_BILINEAR4_H_MMI(%[src], %[dst])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_LOW32
+ RESTRICT_ASM_ALL64
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [a]"+&f"(a), [b]"+&f"(b)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int a = 8 - mx, b = mx;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear4_v_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ int c = 8 - my, d = my;
+ double ftmp[7];
+ uint32_t tmp[1];
+ mips_reg src1;
+ DECLARE_VAR_LOW32;
+ DECLARE_VAR_ALL64;
+
+ /*
+ dst[0] = (c * src[0] + d * src[ sstride] + 4) >> 3;
+ dst[1] = (c * src[1] + d * src[1 + sstride] + 4) >> 3;
+ dst[2] = (c * src[2] + d * src[2 + sstride] + 4) >> 3;
+ dst[3] = (c * src[3] + d * src[3 + sstride] + 4) >> 3;
+ */
+ __asm__ volatile (
+ "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t"
+ "li %[tmp0], 0x03 \n\t"
+ "mtc1 %[tmp0], %[ftmp4] \n\t"
+ "pshufh %[c], %[c], %[ftmp0] \n\t"
+ "pshufh %[d], %[d], %[ftmp0] \n\t"
+
+ "1: \n\t"
+ PUT_VP8_BILINEAR4_V_MMI(%[src], %[src1], %[dst], %[sstride])
+
+ "addiu %[h], %[h], -0x01 \n\t"
+ PTR_ADDU "%[src], %[src], %[sstride] \n\t"
+ PTR_ADDU "%[dst], %[dst], %[dstride] \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]),
+ [tmp0]"=&r"(tmp[0]),
+ RESTRICT_ASM_LOW32
+ RESTRICT_ASM_ALL64
+ [src1]"=&r"(src1),
+ [h]"+&r"(h),
+ [dst]"+&r"(dst), [src]"+&r"(src),
+ [c]"+&f"(c), [d]"+&f"(d)
+ : [sstride]"r"((mips_reg)sstride),
+ [dstride]"r"((mips_reg)dstride),
+ [ff_pw_4]"f"(ff_pw_4)
+ : "memory"
+ );
+#else
+ int c = 8 - my, d = my;
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3;
+ dst += dstride;
+ src += sstride;
+ }
+#endif
+}
+
+void ff_put_vp8_bilinear4_hv_mmi(uint8_t *dst, ptrdiff_t dstride, uint8_t *src,
+ ptrdiff_t sstride, int h, int mx, int my)
+{
+#if 1
+ DECLARE_ALIGNED(4, uint8_t, tmp_array[36]);
+ uint8_t *tmp = tmp_array;
+
+ ff_put_vp8_bilinear4_h_mmi(tmp, 4, src, sstride, h + 1, mx, my);
+ ff_put_vp8_bilinear4_v_mmi(dst, dstride, tmp, 4, h, mx, my);
+#else
+ int a = 8 - mx, b = mx;
+ int c = 8 - my, d = my;
+ int x, y;
+ uint8_t tmp_array[36];
+ uint8_t *tmp = tmp_array;
+
+ for (y = 0; y < h + 1; y++) {
+ for (x = 0; x < 4; x++)
+ tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3;
+ tmp += 4;
+ src += sstride;
+ }
+
+ tmp = tmp_array;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < 4; x++)
+ dst[x] = (c * tmp[x] + d * tmp[x + 4] + 4) >> 3;
+ dst += dstride;
+ tmp += 4;
+ }
+#endif
+}
--
2.1.0
2
1