1 /*
2 	mangle: support defines for preprocessed assembler
3 
4 	copyright 1995-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
5 	see COPYING and AUTHORS files in distribution or http://mpg123.org
6 
7 	This once started out as mangle.h from MPlayer, but you can't really call it derived work... the small part that in principle stems from MPlayer also being not very special (once you decided to use such a header at all, it's quite obvious material).
8 */
9 
10 #ifndef __MANGLE_H
11 #define __MANGLE_H
12 
13 #include "config.h"
14 #include "intsym.h"
15 
16 #if (defined OPT_I486)  || (defined OPT_I586) || (defined OPT_I586_DITHER) \
17  || (defined OPT_MMX)   || (defined OPT_SSE)  || (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) \
18  || (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \
19  || (defined OPT_SSE_VINTAGE)
20 #define OPT_X86
21 #endif
22 
23 #ifdef CCALIGN
24 #define MOVUAPS movaps
25 #else
26 #define MOVUAPS movups
27 #endif
28 
29 /*
30 	ALIGNX: align to X bytes
31 	This differs per compiler/platform in taking the byte count or an exponent for base 2.
32 	A way out is balign, if the assembler supports it (gas extension).
33 */
34 
35 #ifdef ASMALIGN_BALIGN
36 
37 #define ALIGN4  .balign 4
38 #define ALIGN8  .balign 8
39 #define ALIGN16 .balign 16
40 #define ALIGN32 .balign 32
41 #define ALIGN64 .balign 64
42 
43 #else
44 
45 #ifdef ASMALIGN_EXP
46 #define ALIGN4  .align 2
47 #define ALIGN8  .align 3
48 #define ALIGN16 .align 4
49 #define ALIGN32 .align 5
50 #define ALIGN64 .align 6
51 #else
52 #ifdef ASMALIGN_BYTE
53 #define ALIGN4  .align 4
54 #define ALIGN8  .align 8
55 #define ALIGN16 .align 16
56 #define ALIGN32 .align 32
57 #define ALIGN64 .align 64
58 #else
59 #ifdef ASMALIGN_ARMASM
60 #define ALIGN4  ALIGN 4
61 #define ALIGN8  ALIGN 8
62 #define ALIGN16 ALIGN 16
63 #define ALIGN32 ALIGN 32
64 #define ALIGN64 ALIGN 64
65 #else
66 #error "Dunno how assembler alignment works. Please specify."
67 #endif
68 #endif
69 #endif
70 
71 #endif
72 
73 #define MANGLE_MACROCAT_REALLY(a, b) a ## b
74 #define MANGLE_MACROCAT(a, b) MANGLE_MACROCAT_REALLY(a, b)
75 /* Feel free to add more to the list, eg. a.out IMO */
76 #if defined(__USER_LABEL_PREFIX__)
77 #define ASM_NAME(a) MANGLE_MACROCAT(__USER_LABEL_PREFIX__,a)
78 #define ASM_VALUE(a) MANGLE_MACROCAT($,ASM_NAME(a))
79 #elif defined(__CYGWIN__) || defined(_WIN32) && !defined (_WIN64) && !defined (_M_ARM) || defined(__OS2__) || \
80    (defined(__OpenBSD__) && !defined(__ELF__)) || defined(__APPLE__)
81 #define ASM_NAME(a) MANGLE_MACROCAT(_,a)
82 #define ASM_VALUE(a) MANGLE_MACROCAT($_,a)
83 #else
84 #define ASM_NAME(a) a
85 #define ASM_VALUE(a) MANGLE_MACROCAT($,a)
86 #endif
87 
88 /* Enable position-independent code for certain platforms. */
89 
90 #if defined(OPT_X86)
91 
92 #define _EBX_ %ebx
93 
94 #if defined(PIC) && defined(__ELF__)
95 
96 /* ELF binaries (Unix/Linux) */
97 #define LOCAL_VAR(a) a ## @GOTOFF(_EBX_)
98 #define GLOBAL_VAR(a) ASM_NAME(a) ## @GOTOFF(_EBX_)
99 #define GLOBAL_VAR_PTR(a) ASM_NAME(a) ## @GOT(_EBX_)
100 #define FUNC(a) ASM_NAME(a)
101 #define EXTERNAL_FUNC(a) ASM_NAME(a) ## @PLT
102 #undef ASM_VALUE
103 #define ASM_VALUE(a) MANGLE_MACROCAT($,a) ##@GOTOFF
104 #define GET_GOT \
105 	call 1f; \
106 1: \
107 	pop _EBX_; \
108 2: \
109 	addl $_GLOBAL_OFFSET_TABLE_ + (2b-1b), _EBX_
110 #define PREPARE_GOT pushl _EBX_
111 #define RESTORE_GOT popl _EBX_
112 
113 #elif defined(PIC) && defined(__APPLE__)
114 
115 /* Mach-O binaries (OSX/iOS) */
116 #define LOCAL_VAR(a) a ## - Lpic_base(_EBX_)
117 #define GLOBAL_VAR(a) .err This ABI cannot access non-local symbols directly.
118 #define GLOBAL_VAR_PTR(a) L_ ## a ## - Lpic_base(_EBX_)
119 #define FUNC(a) L_ ## a
120 #define EXTERNAL_FUNC(a) L_ ## a
121 #define GET_GOT \
122 	call Lpic_base; \
123 Lpic_base: \
124 	pop _EBX_
125 #define PREPARE_GOT pushl _EBX_
126 #define RESTORE_GOT popl _EBX_
127 
128 #else
129 
130 /* Dummies for everyone else. */
131 #define LOCAL_VAR(a) a
132 #define GLOBAL_VAR ASM_NAME
133 #define GLOBAL_VAR_PTR(a) .err Cannot use indirect addressing in non-PIC object.
134 #define FUNC ASM_NAME
135 #define EXTERNAL_FUNC ASM_NAME
136 #define GET_GOT
137 #define PREPARE_GOT
138 #define RESTORE_GOT
139 
140 #endif /* PIC variants */
141 
142 #endif /* OPT_X86 */
143 
144 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
145 #define COMM(a,b,c) .comm a,b
146 #else
147 #define COMM(a,b,c) .comm a,b,c
148 #endif
149 /* more hacks for macosx; no .bss ... */
150 #ifdef __APPLE__
151 #define BSS .data
152 #else
153 #define BSS .bss
154 #endif
155 
156 /* armasm for WIN32 UWP */
157 #ifdef _M_ARM
158 #define GLOBAL_SYMBOL EXPORT
159 #else
160 #define GLOBAL_SYMBOL .globl
161 #endif
162 
163 /* Mark non-executable stack.
164    It's mainly for GNU on Linux... who else does (not) like this? */
165 #if !defined(__SUNPRO_C) && defined(__linux__) && defined(__ELF__)
166 #if defined(__arm__)
167 #define NONEXEC_STACK .section .note.GNU-stack,"",%progbits
168 #else
169 #define NONEXEC_STACK .section .note.GNU-stack,"",@progbits
170 #endif
171 #else
172 #define NONEXEC_STACK
173 #endif
174 
175 #if (defined(__x86_64__) || defined(_M_X64)) && (defined(_WIN64) || defined (__CYGWIN__))
176 #define IS_MSABI 1 /* Not using SYSV */
177 #endif
178 
179 /* Macros for +-4GiB PC-relative addressing on AArch64 */
180 #ifdef __APPLE__
181 #define AARCH64_PCREL_HI(label) label@PAGE
182 #define AARCH64_PCREL_LO(label) label@PAGEOFF
183 #else
184 #define AARCH64_PCREL_HI(label) label
185 #define AARCH64_PCREL_LO(label) :lo12:label
186 #endif
187 
188 #ifdef __APPLE__
189 #define AARCH64_DUP_4S(dst, src, elem) dup.4s dst, src[elem]
190 #define AARCH64_DUP_2D(dst, src, elem) dup.2d dst, src[elem]
191 #define AARCH64_SQXTN2_8H(dst, src) sqxtn2.8h dst, src
192 #else
193 #define AARCH64_DUP_4S(dst, src, elem) dup dst.4s, src.s[elem]
194 #define AARCH64_DUP_2D(dst, src, elem) dup dst.2d, src.d[elem]
195 #define AARCH64_SQXTN2_8H(dst, src) sqxtn2 dst.8h, src.4s
196 #endif
197 
198 #endif /* !__MANGLE_H */
199 
200