FFmpeg
asm.h
Go to the documentation of this file.
1 /*
2  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef AVUTIL_X86_ASM_H
22 #define AVUTIL_X86_ASM_H
23 
24 #include <stdint.h>
25 #include "config.h"
26 
27 typedef struct xmm_reg { uint64_t a, b; } xmm_reg;
28 typedef struct ymm_reg { uint64_t a, b, c, d; } ymm_reg;
29 
30 #if ARCH_X86_64
31 # define FF_OPSIZE "q"
32 # define FF_REG_a "rax"
33 # define FF_REG_b "rbx"
34 # define FF_REG_c "rcx"
35 # define FF_REG_d "rdx"
36 # define FF_REG_D "rdi"
37 # define FF_REG_S "rsi"
38 # define FF_PTR_SIZE "8"
39 typedef int64_t x86_reg;
40 
41 /* FF_REG_SP is defined in Solaris sys headers, so use FF_REG_sp */
42 # define FF_REG_sp "rsp"
43 # define FF_REG_BP "rbp"
44 # define FF_REGBP rbp
45 # define FF_REGa rax
46 # define FF_REGb rbx
47 # define FF_REGc rcx
48 # define FF_REGd rdx
49 # define FF_REGSP rsp
50 
51 #elif ARCH_X86_32
52 
53 # define FF_OPSIZE "l"
54 # define FF_REG_a "eax"
55 # define FF_REG_b "ebx"
56 # define FF_REG_c "ecx"
57 # define FF_REG_d "edx"
58 # define FF_REG_D "edi"
59 # define FF_REG_S "esi"
60 # define FF_PTR_SIZE "4"
61 typedef int32_t x86_reg;
62 
63 # define FF_REG_sp "esp"
64 # define FF_REG_BP "ebp"
65 # define FF_REGBP ebp
66 # define FF_REGa eax
67 # define FF_REGb ebx
68 # define FF_REGc ecx
69 # define FF_REGd edx
70 # define FF_REGSP esp
71 #else
72 typedef int x86_reg;
73 #endif
74 
75 #define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE))
76 #define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE))
77 
78 #if ARCH_X86_64 && defined(PIC)
79 # define BROKEN_RELOCATIONS 1
80 #endif
81 
82 /*
83  * If gcc is not set to support sse (-msse) it will not accept xmm registers
84  * in the clobber list for inline asm. XMM_CLOBBERS takes a list of xmm
85  * registers to be marked as clobbered and evaluates to nothing if they are
86  * not supported, or to the list itself if they are supported. Since a clobber
87  * list may not be empty, XMM_CLOBBERS_ONLY should be used if the xmm
88  * registers are the only in the clobber list.
89  * For example a list with "eax" and "xmm0" as clobbers should become:
90  * : XMM_CLOBBERS("xmm0",) "eax"
91  * and a list with only "xmm0" should become:
92  * XMM_CLOBBERS_ONLY("xmm0")
93  */
94 #if HAVE_XMM_CLOBBERS
95 # define XMM_CLOBBERS(...) __VA_ARGS__
96 # define XMM_CLOBBERS_ONLY(...) : __VA_ARGS__
97 #else
98 # define XMM_CLOBBERS(...)
99 # define XMM_CLOBBERS_ONLY(...)
100 #endif
101 
102 /* Use to export labels from asm. */
103 #define LABEL_MANGLE(a) EXTERN_PREFIX #a
104 
105 // Use rip-relative addressing if compiling PIC code on x86-64.
106 #if ARCH_X86_64 && defined(PIC)
107 # define LOCAL_MANGLE(a) #a "(%%rip)"
108 #else
109 # define LOCAL_MANGLE(a) #a
110 #endif
111 
112 #if HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS
113 # define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a)
114 # define NAMED_CONSTRAINTS_ADD(...)
115 # define NAMED_CONSTRAINTS(...)
116 # define NAMED_CONSTRAINTS_ARRAY_ADD(...)
117 # define NAMED_CONSTRAINTS_ARRAY(...)
118 #else
119  /* When direct symbol references are used in code passed to a compiler that does not support them
120  * then these references need to be converted to named asm constraints instead.
121  * Instead of returning a direct symbol MANGLE now returns a named constraint for that specific symbol.
122  * In order for this to work there must also be a corresponding entry in the asm-interface. To add this
123  * entry use the macro NAMED_CONSTRAINTS() and pass in a list of each symbol reference used in the
124  * corresponding block of code. (e.g. NAMED_CONSTRAINTS(var1,var2,var3) where var1 is the first symbol etc. ).
125  * If there are already existing constraints then use NAMED_CONSTRAINTS_ADD to add to the existing constraint list.
126  */
127 # define MANGLE(a) "%["#a"]"
128  // Intel/MSVC does not correctly expand va-args so we need a rather ugly hack in order to get it to work
129 # define FE_0(P,X) P(X)
130 # define FE_1(P,X,X1) P(X), FE_0(P,X1)
131 # define FE_2(P,X,X1,X2) P(X), FE_1(P,X1,X2)
132 # define FE_3(P,X,X1,X2,X3) P(X), FE_2(P,X1,X2,X3)
133 # define FE_4(P,X,X1,X2,X3,X4) P(X), FE_3(P,X1,X2,X3,X4)
134 # define FE_5(P,X,X1,X2,X3,X4,X5) P(X), FE_4(P,X1,X2,X3,X4,X5)
135 # define FE_6(P,X,X1,X2,X3,X4,X5,X6) P(X), FE_5(P,X1,X2,X3,X4,X5,X6)
136 # define FE_7(P,X,X1,X2,X3,X4,X5,X6,X7) P(X), FE_6(P,X1,X2,X3,X4,X5,X6,X7)
137 # define FE_8(P,X,X1,X2,X3,X4,X5,X6,X7,X8) P(X), FE_7(P,X1,X2,X3,X4,X5,X6,X7,X8)
138 # define FE_9(P,X,X1,X2,X3,X4,X5,X6,X7,X8,X9) P(X), FE_8(P,X1,X2,X3,X4,X5,X6,X7,X8,X9)
139 # define GET_FE_IMPL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME
140 # define GET_FE(A) GET_FE_IMPL A
141 # define GET_FE_GLUE(x, y) x y
142 # define FOR_EACH_VA(P,...) GET_FE_GLUE(GET_FE((__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)), (P,__VA_ARGS__))
143 # define NAME_CONSTRAINT(x) [x] "m"(x)
144  // Parameters are a list of each symbol reference required
145 # define NAMED_CONSTRAINTS_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__)
146  // Same but without comma for when there are no previously defined constraints
147 # define NAMED_CONSTRAINTS(...) FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__)
148  // Same as above NAMED_CONSTRAINTS except used for passing arrays/pointers instead of normal variables
149 # define NAME_CONSTRAINT_ARRAY(x) [x] "m"(*x)
150 # define NAMED_CONSTRAINTS_ARRAY_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__)
151 # define NAMED_CONSTRAINTS_ARRAY(...) FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__)
152 #endif
153 
154 #endif /* AVUTIL_X86_ASM_H */
uint64_t b
Definition: asm.h:27
uint64_t d
Definition: asm.h:28
Definition: asm.h:27
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
uint64_t a
Definition: asm.h:27
int32_t
Definition: asm.h:28
int x86_reg
Definition: asm.h:72