1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * simple math operations
3cabdff1aSopenharmony_ci * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#ifndef AVCODEC_X86_MATHOPS_H
23cabdff1aSopenharmony_ci#define AVCODEC_X86_MATHOPS_H
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#include "config.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/common.h"
28cabdff1aSopenharmony_ci#include "libavutil/x86/asm.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#if HAVE_INLINE_ASM
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#if ARCH_X86_32
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci#define MULL MULL
35cabdff1aSopenharmony_cistatic av_always_inline av_const int MULL(int a, int b, unsigned shift)
36cabdff1aSopenharmony_ci{
37cabdff1aSopenharmony_ci    int rt, dummy;
38cabdff1aSopenharmony_ci    if (__builtin_constant_p(shift))
39cabdff1aSopenharmony_ci    __asm__ (
40cabdff1aSopenharmony_ci        "imull %3               \n\t"
41cabdff1aSopenharmony_ci        "shrdl %4, %%edx, %%eax \n\t"
42cabdff1aSopenharmony_ci        :"=a"(rt), "=d"(dummy)
43cabdff1aSopenharmony_ci        :"a"(a), "rm"(b), "i"(shift & 0x1F)
44cabdff1aSopenharmony_ci    );
45cabdff1aSopenharmony_ci    else
46cabdff1aSopenharmony_ci        __asm__ (
47cabdff1aSopenharmony_ci            "imull %3               \n\t"
48cabdff1aSopenharmony_ci            "shrdl %4, %%edx, %%eax \n\t"
49cabdff1aSopenharmony_ci            :"=a"(rt), "=d"(dummy)
50cabdff1aSopenharmony_ci            :"a"(a), "rm"(b), "c"((uint8_t)shift)
51cabdff1aSopenharmony_ci        );
52cabdff1aSopenharmony_ci    return rt;
53cabdff1aSopenharmony_ci}
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ci#define MULH MULH
56cabdff1aSopenharmony_cistatic av_always_inline av_const int MULH(int a, int b)
57cabdff1aSopenharmony_ci{
58cabdff1aSopenharmony_ci    int rt, dummy;
59cabdff1aSopenharmony_ci    __asm__ (
60cabdff1aSopenharmony_ci        "imull %3"
61cabdff1aSopenharmony_ci        :"=d"(rt), "=a"(dummy)
62cabdff1aSopenharmony_ci        :"a"(a), "rm"(b)
63cabdff1aSopenharmony_ci    );
64cabdff1aSopenharmony_ci    return rt;
65cabdff1aSopenharmony_ci}
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci#define MUL64 MUL64
68cabdff1aSopenharmony_cistatic av_always_inline av_const int64_t MUL64(int a, int b)
69cabdff1aSopenharmony_ci{
70cabdff1aSopenharmony_ci    int64_t rt;
71cabdff1aSopenharmony_ci    __asm__ (
72cabdff1aSopenharmony_ci        "imull %2"
73cabdff1aSopenharmony_ci        :"=A"(rt)
74cabdff1aSopenharmony_ci        :"a"(a), "rm"(b)
75cabdff1aSopenharmony_ci    );
76cabdff1aSopenharmony_ci    return rt;
77cabdff1aSopenharmony_ci}
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci#endif /* ARCH_X86_32 */
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci#if HAVE_I686
82cabdff1aSopenharmony_ci/* median of 3 */
83cabdff1aSopenharmony_ci#define mid_pred mid_pred
84cabdff1aSopenharmony_cistatic inline av_const int mid_pred(int a, int b, int c)
85cabdff1aSopenharmony_ci{
86cabdff1aSopenharmony_ci    int i=b;
87cabdff1aSopenharmony_ci    __asm__ (
88cabdff1aSopenharmony_ci        "cmp    %2, %1 \n\t"
89cabdff1aSopenharmony_ci        "cmovg  %1, %0 \n\t"
90cabdff1aSopenharmony_ci        "cmovg  %2, %1 \n\t"
91cabdff1aSopenharmony_ci        "cmp    %3, %1 \n\t"
92cabdff1aSopenharmony_ci        "cmovl  %3, %1 \n\t"
93cabdff1aSopenharmony_ci        "cmp    %1, %0 \n\t"
94cabdff1aSopenharmony_ci        "cmovg  %1, %0 \n\t"
95cabdff1aSopenharmony_ci        :"+&r"(i), "+&r"(a)
96cabdff1aSopenharmony_ci        :"r"(b), "r"(c)
97cabdff1aSopenharmony_ci    );
98cabdff1aSopenharmony_ci    return i;
99cabdff1aSopenharmony_ci}
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci#if HAVE_6REGS
102cabdff1aSopenharmony_ci#define COPY3_IF_LT(x, y, a, b, c, d)\
103cabdff1aSopenharmony_ci__asm__ volatile(\
104cabdff1aSopenharmony_ci    "cmpl  %0, %3       \n\t"\
105cabdff1aSopenharmony_ci    "cmovl %3, %0       \n\t"\
106cabdff1aSopenharmony_ci    "cmovl %4, %1       \n\t"\
107cabdff1aSopenharmony_ci    "cmovl %5, %2       \n\t"\
108cabdff1aSopenharmony_ci    : "+&r" (x), "+&r" (a), "+r" (c)\
109cabdff1aSopenharmony_ci    : "r" (y), "r" (b), "r" (d)\
110cabdff1aSopenharmony_ci);
111cabdff1aSopenharmony_ci#endif /* HAVE_6REGS */
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci#endif /* HAVE_I686 */
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci#define MASK_ABS(mask, level)                   \
116cabdff1aSopenharmony_ci    __asm__ ("cdq                    \n\t"      \
117cabdff1aSopenharmony_ci             "xorl %1, %0            \n\t"      \
118cabdff1aSopenharmony_ci             "subl %1, %0            \n\t"      \
119cabdff1aSopenharmony_ci             : "+a"(level), "=&d"(mask))
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci// avoid +32 for shift optimization (gcc should do that ...)
122cabdff1aSopenharmony_ci#define NEG_SSR32 NEG_SSR32
123cabdff1aSopenharmony_cistatic inline  int32_t NEG_SSR32( int32_t a, int8_t s){
124cabdff1aSopenharmony_ci    if (__builtin_constant_p(s))
125cabdff1aSopenharmony_ci    __asm__ ("sarl %1, %0\n\t"
126cabdff1aSopenharmony_ci         : "+r" (a)
127cabdff1aSopenharmony_ci         : "i" (-s & 0x1F)
128cabdff1aSopenharmony_ci    );
129cabdff1aSopenharmony_ci    else
130cabdff1aSopenharmony_ci        __asm__ ("sarl %1, %0\n\t"
131cabdff1aSopenharmony_ci               : "+r" (a)
132cabdff1aSopenharmony_ci               : "c" ((uint8_t)(-s))
133cabdff1aSopenharmony_ci        );
134cabdff1aSopenharmony_ci    return a;
135cabdff1aSopenharmony_ci}
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ci#define NEG_USR32 NEG_USR32
138cabdff1aSopenharmony_cistatic inline uint32_t NEG_USR32(uint32_t a, int8_t s){
139cabdff1aSopenharmony_ci    if (__builtin_constant_p(s))
140cabdff1aSopenharmony_ci    __asm__ ("shrl %1, %0\n\t"
141cabdff1aSopenharmony_ci         : "+r" (a)
142cabdff1aSopenharmony_ci         : "i" (-s & 0x1F)
143cabdff1aSopenharmony_ci    );
144cabdff1aSopenharmony_ci    else
145cabdff1aSopenharmony_ci        __asm__ ("shrl %1, %0\n\t"
146cabdff1aSopenharmony_ci               : "+r" (a)
147cabdff1aSopenharmony_ci               : "c" ((uint8_t)(-s))
148cabdff1aSopenharmony_ci        );
149cabdff1aSopenharmony_ci    return a;
150cabdff1aSopenharmony_ci}
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ci#endif /* HAVE_INLINE_ASM */
153cabdff1aSopenharmony_ci#endif /* AVCODEC_X86_MATHOPS_H */
154