macos assembly llvm intel vorbis

macos - Error MAC OSX Intel LLVM Assembler(hace que el cargador Vorbis OGG se bloquee)



assembly (2)

¡Excelente! Gracias. Otra solución es simplemente eliminar el asm por completo. Aquí hay un parche:

--- lib/os.h 2011-11-13 20:36:24.000000000 -0500 +++ lib/os.h 2011-11-15 18:45:00.000000000 -0500 @@ -93,27 +93,16 @@ typedef ogg_int16_t vorbis_fpu_control; static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ - ogg_int16_t ret; - ogg_int16_t temp; - __asm__ __volatile__("fnstcw %0/n/t" - "movw %0,%%dx/n/t" - "andw $62463,%%dx/n/t" - "movw %%dx,%1/n/t" - "fldcw %1/n/t":"=m"(ret):"m"(temp): "dx"); - *fpu=ret; } static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ - __asm__ __volatile__("fldcw %0":: "m"(fpu)); } /* assumes the FPU is in round mode! */ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise, we get extra fst/fld to truncate precision */ - int i; - __asm__("fistl %0": "=m"(i) : "t"(f)); - return(i); + return (int)floor(f+.5); } #endif /* Special i386 GCC implementation */

Tenía un error misterioso al cargar archivos Vorbis Ogg en Mac OSX. El primer archivo se carga correctamente, el segundo falla en algún código que indica que el archivo está dañado, lo mismo ocurre incluso si cargué el mismo archivo exacto dos veces.

Después de largas horas de depuración profunda dentro de Vorbis descubrí que el error es causado por la función del sistema "pow" (doble potencia de) que devuelve a (nan) para una entrada completamente válida, y eso ocurre solo en la segunda llamada a (ov_read ), en la primera llamada, los mismos valores exactos pasados ​​a "pow" devuelven resultados válidos.

8 horas después y mucha documentación de Intel x87 leyendo, encontré el problema. Para resumir, hay una función en el interior de vorbis "vorbis_ftoi" que usa este código ensamblador:

__asm__("fistl %0": "=m"(i) : "t"(f));

Que debería presionar y abrir en la pila Intel FPU. Sin embargo, en LLVM genera este código:

fld QWORD PTR [ebp-0x20] fist DWORD PTR [ebp-0x14]

Lo que empuja en la pila pero nunca aparece provocando un desbordamiento de la pila FPU. Y eso obviamente es un error en LLVM

El código apropiado generado por GCC se ve así:

fld QWORD PTR [ebp-0x20] fist DWORD PTR [ebp-0xc] fstp st(0) // pops off the stack

Perdí un día y medio y algunos bytes de mi brian aprendiendo algo de basura (Conjunto de instrucciones x87 y Registros) sobre esto, así que pensé en compartirlo.

Auday


Parche más simple, tiene efecto solo cuando se compila con llvm:

--- Xiph/vorbis/os.h Mon Mar 28 08:42:43 2011 +++ Xiph/vorbis/os.h Thu Feb 02 14:20:27 2012 @@ -81,7 +81,7 @@ /* Special i386 GCC implementation */ -#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) +#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) && !defined(__llvm__) # define VORBIS_FPU_CONTROL /* both GCC and MSVC are kinda stupid about rounding/casting to int. Because of encapsulation constraints (GCC can''t see inside the asm

Lamentablemente, no tengo suficiente reputación para votar por el OP, pero sé que estoy agradecido por su hallazgo. Gracias.