annotate src/libvorbis-1.3.3/lib/os.h @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 #ifndef _OS_H
Chris@1 2 #define _OS_H
Chris@1 3 /********************************************************************
Chris@1 4 * *
Chris@1 5 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 6 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 7 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 8 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 9 * *
Chris@1 10 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
Chris@1 11 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 12 * *
Chris@1 13 ********************************************************************
Chris@1 14
Chris@1 15 function: #ifdef jail to whip a few platforms into the UNIX ideal.
Chris@1 16 last mod: $Id: os.h 16227 2009-07-08 06:58:46Z xiphmont $
Chris@1 17
Chris@1 18 ********************************************************************/
Chris@1 19
Chris@1 20 #ifdef HAVE_CONFIG_H
Chris@1 21 #include "config.h"
Chris@1 22 #endif
Chris@1 23
Chris@1 24 #include <math.h>
Chris@1 25 #include <ogg/os_types.h>
Chris@1 26
Chris@1 27 #include "misc.h"
Chris@1 28
Chris@1 29 #ifndef _V_IFDEFJAIL_H_
Chris@1 30 # define _V_IFDEFJAIL_H_
Chris@1 31
Chris@1 32 # ifdef __GNUC__
Chris@1 33 # define STIN static __inline__
Chris@1 34 # elif _WIN32
Chris@1 35 # define STIN static __inline
Chris@1 36 # else
Chris@1 37 # define STIN static
Chris@1 38 # endif
Chris@1 39
Chris@1 40 #ifdef DJGPP
Chris@1 41 # define rint(x) (floor((x)+0.5f))
Chris@1 42 #endif
Chris@1 43
Chris@1 44 #ifndef M_PI
Chris@1 45 # define M_PI (3.1415926536f)
Chris@1 46 #endif
Chris@1 47
Chris@1 48 #if defined(_WIN32) && !defined(__SYMBIAN32__)
Chris@1 49 # include <malloc.h>
Chris@1 50 # define rint(x) (floor((x)+0.5f))
Chris@1 51 # define NO_FLOAT_MATH_LIB
Chris@1 52 # define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
Chris@1 53 #endif
Chris@1 54
Chris@1 55 #if defined(__SYMBIAN32__) && defined(__WINS__)
Chris@1 56 void *_alloca(size_t size);
Chris@1 57 # define alloca _alloca
Chris@1 58 #endif
Chris@1 59
Chris@1 60 #ifndef FAST_HYPOT
Chris@1 61 # define FAST_HYPOT hypot
Chris@1 62 #endif
Chris@1 63
Chris@1 64 #endif
Chris@1 65
Chris@1 66 #ifdef HAVE_ALLOCA_H
Chris@1 67 # include <alloca.h>
Chris@1 68 #endif
Chris@1 69
Chris@1 70 #ifdef USE_MEMORY_H
Chris@1 71 # include <memory.h>
Chris@1 72 #endif
Chris@1 73
Chris@1 74 #ifndef min
Chris@1 75 # define min(x,y) ((x)>(y)?(y):(x))
Chris@1 76 #endif
Chris@1 77
Chris@1 78 #ifndef max
Chris@1 79 # define max(x,y) ((x)<(y)?(y):(x))
Chris@1 80 #endif
Chris@1 81
Chris@1 82
Chris@1 83 /* Special i386 GCC implementation */
Chris@1 84 #if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
Chris@1 85 # define VORBIS_FPU_CONTROL
Chris@1 86 /* both GCC and MSVC are kinda stupid about rounding/casting to int.
Chris@1 87 Because of encapsulation constraints (GCC can't see inside the asm
Chris@1 88 block and so we end up doing stupid things like a store/load that
Chris@1 89 is collectively a noop), we do it this way */
Chris@1 90
Chris@1 91 /* we must set up the fpu before this works!! */
Chris@1 92
Chris@1 93 typedef ogg_int16_t vorbis_fpu_control;
Chris@1 94
Chris@1 95 static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
Chris@1 96 ogg_int16_t ret;
Chris@1 97 ogg_int16_t temp;
Chris@1 98 __asm__ __volatile__("fnstcw %0\n\t"
Chris@1 99 "movw %0,%%dx\n\t"
Chris@1 100 "andw $62463,%%dx\n\t"
Chris@1 101 "movw %%dx,%1\n\t"
Chris@1 102 "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
Chris@1 103 *fpu=ret;
Chris@1 104 }
Chris@1 105
Chris@1 106 static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
Chris@1 107 __asm__ __volatile__("fldcw %0":: "m"(fpu));
Chris@1 108 }
Chris@1 109
Chris@1 110 /* assumes the FPU is in round mode! */
Chris@1 111 static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
Chris@1 112 we get extra fst/fld to
Chris@1 113 truncate precision */
Chris@1 114 int i;
Chris@1 115 __asm__("fistl %0": "=m"(i) : "t"(f));
Chris@1 116 return(i);
Chris@1 117 }
Chris@1 118 #endif /* Special i386 GCC implementation */
Chris@1 119
Chris@1 120
Chris@1 121 /* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
Chris@1 122 * 64 bit compiler */
Chris@1 123 #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
Chris@1 124 # define VORBIS_FPU_CONTROL
Chris@1 125
Chris@1 126 typedef ogg_int16_t vorbis_fpu_control;
Chris@1 127
Chris@1 128 static __inline int vorbis_ftoi(double f){
Chris@1 129 int i;
Chris@1 130 __asm{
Chris@1 131 fld f
Chris@1 132 fistp i
Chris@1 133 }
Chris@1 134 return i;
Chris@1 135 }
Chris@1 136
Chris@1 137 static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
Chris@1 138 }
Chris@1 139
Chris@1 140 static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
Chris@1 141 }
Chris@1 142
Chris@1 143 #endif /* Special MSVC 32 bit implementation */
Chris@1 144
Chris@1 145
Chris@1 146 /* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
Chris@1 147 done safely because all x86_64 CPUs supports SSE2. */
Chris@1 148 #if (defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__))
Chris@1 149 # define VORBIS_FPU_CONTROL
Chris@1 150
Chris@1 151 typedef ogg_int16_t vorbis_fpu_control;
Chris@1 152
Chris@1 153 #include <emmintrin.h>
Chris@1 154 static __inline int vorbis_ftoi(double f){
Chris@1 155 return _mm_cvtsd_si32(_mm_load_sd(&f));
Chris@1 156 }
Chris@1 157
Chris@1 158 static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
Chris@1 159 }
Chris@1 160
Chris@1 161 static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
Chris@1 162 }
Chris@1 163
Chris@1 164 #endif /* Special MSVC x64 implementation */
Chris@1 165
Chris@1 166
Chris@1 167 /* If no special implementation was found for the current compiler / platform,
Chris@1 168 use the default implementation here: */
Chris@1 169 #ifndef VORBIS_FPU_CONTROL
Chris@1 170
Chris@1 171 typedef int vorbis_fpu_control;
Chris@1 172
Chris@1 173 static int vorbis_ftoi(double f){
Chris@1 174 /* Note: MSVC and GCC (at least on some systems) round towards zero, thus,
Chris@1 175 the floor() call is required to ensure correct roudning of
Chris@1 176 negative numbers */
Chris@1 177 return (int)floor(f+.5);
Chris@1 178 }
Chris@1 179
Chris@1 180 /* We don't have special code for this compiler/arch, so do it the slow way */
Chris@1 181 # define vorbis_fpu_setround(vorbis_fpu_control) {}
Chris@1 182 # define vorbis_fpu_restore(vorbis_fpu_control) {}
Chris@1 183
Chris@1 184 #endif /* default implementation */
Chris@1 185
Chris@1 186 #endif /* _OS_H */