У меня была загадочная ошибка при загрузке файлов Vorbis Ogg на Mac OSX. Первый файл загружен правильно, второй - сбой в некотором коде, который указывает, что файл поврежден, то же самое происходит, даже если я загружаю один и тот же точный файл дважды.
После долгих часов глубокой отладки внутри Vorbis я обнаружил, что ошибка вызвана системной функцией "pow" (двойная степень), возвращающей (nan) для полностью корректного ввода, и это происходит только при втором вызове to (ov_read), при первом вызове те же самые точные значения, переданные "pow", возвращают действительный результат.
8 часов спустя и много чтения документации Intel x87 я обнаружил проблему. Короче говоря, внутри vorbis есть функция vorbis_ftoi, которая использует этот код сборки:
__asm__("fistl %0": "=m"(i) : "t"(f));
Что должно вытолкнуть и вытолкнуть в стек Intel FPU. Однако на LLVM он генерирует этот код:
fld QWORD PTR [ebp-0x20]
fist DWORD PTR [ebp-0x14]
Который выталкивает в стек, но никогда не всплывает, вызывая переполнение стека FPU. И это, очевидно, ошибка в LLVM
Правильный код, сгенерированный GCC, выглядит следующим образом:
fld QWORD PTR [ebp-0x20]
fist DWORD PTR [ebp-0xc]
fstp st(0) // pops off the stack
Я потратил полтора дня и несколько байтов своего Брайана, изучая некоторый мусор (x87 Instruction Set and Registers) по этому поводу, поэтому я решил поделиться им.
Auday