repstosw 18 25 мая, 2020 Опубликовано 25 мая, 2020 (изменено) · Жалоба Добрый день! Запустил вывод картинки на дисплей и вывод звука через встроенный кодек МК Allwinner A13 под голое железо(без ОС и прочего). Обнаружилась проблема: если активно работать с видео, то обработчик прерывания воспроизведения звука звука завешивает процессор в Abort. Код выполняется с внешней памяти с адреса 0x40000000. MMU , кеширование, предсказание ветвления включены. crt0.s приводил к повисанию, libc не инициализирована. Пришлось сочинять свой стартап. Может что-то упустил. Звук через Normal DMA, канал 0. Прерывания по опустошению половины- и полного- буфера. Буфер выравнен на 32 байта. Буфер некешируем, но буферизован (MMU). Буфер во внешней DDR памяти. Видео: одна поверхность через TCON0, рендерер - composer. Используется анимация изображения, для отрисовки делал 2 варианта: 1) во время обратного хода луча по кадру - переключаю адрес памяти отображения буфера. Показываю буфер-1, рисую в буфере-2. Затем наоборот. 2) во время обратного хода луча по кадру - через Shared DMA(канал 0) перевидываю с заднего буфера в отображаемый буфер. Обратный ход луча по кадру проверяю через GPIO (просто завёл сигнал с VSYNC на свободный пин), так как прерывание по VBLANK не совсем удобно, так как там уже звук. Доступен один вектор -IRQ. Остальные - исключения, SWI и FIQ (который жестко привязан к NMI). В обработчике прерывания от "звукового DMA" пишу единицы в соответствующие биты регистра состояния (подтверждение прерывания). По отдельности видео и звук работают, но одновременно - зависает! Компилирую всё это дело тулчейном GCC-ARM-NONE-EABI v.9. По линковщику вопрос. Использую C++, new/delete, malloc/free. Вроде настроил всё правильно - адреса из кучи выделяются. Если несложно, скиньте пожалуйста скрипт lds для GCC, который был бы настроен на фиксированный адерес, и в котором можно задавать размер: стека, кучи, bss и прочего. Ниже скрипт для линковщика: Spoiler MEM_SIZE = 0x04000000 ; /* размер доступной памяти */ ROM_BASE = 0x40000000 ; /* стартовый адрес */ ROM_SIZE = 0x00180000 ; RAM_BASE = ROM_BASE + ROM_SIZE ; RAM_SIZE = MEM_SIZE - ROM_SIZE ; ENTRY(Entry) MEMORY { ROM (XRW) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE RAM (XRW) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE } SECTIONS { .text : { init.o (.text) *(.text) } > ROM .ivc : {. = ALIGN(32); *(.ivc) *(.rodata)} > ROM .rodata : { *(.rodata) } > ROM __exidx_start = .; .ARM.exidx : { *(.ARM.exidx) } > ROM __exidx_end = .; .heap : { __heap_start__ = .; end = __heap_start__; _end = end; __end = end; *(.heap*). = . + 0x1400000; __heap_end__ = .; __HeapLimit = __heap_end__; } > RAM .bss : { . = ALIGN(4); __bss_start__ = .; *(.bss*). = . + 0x1400000; . = ALIGN(4); __bss_end__ = .; } > RAM .stack : { . = ALIGN(256); __StackLimit = . ; *(.stack*). = . + 0x200000; __StackTop = .; } > RAM _stack = __StackTop; } Изменено 25 мая, 2020 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 27 мая, 2020 Опубликовано 27 мая, 2020 · Жалоба Что, всё так глухо, раз никто не написал ничего ? Причина была в крайне неудачной реализации системы прерываний в A13 - в обработчике надолго застревать нельзя. А это значит, прощай декод фрейма в обработчике. Вынес декод в цикл программы, а в прерывании оставил только взыедение флажка готовности. Было так: void __attribute__ ((interrupt ("IRQ"))) irq_handler(void) { s=DMA_IRQ_PEND_STAS_REG&3; if(s) //проверяем, что источник прерывания - DMA по опустошению половины или всего { DMA_IRQ_PEND_STAS_REG|=s; //подтверждаем нужное прерывание, записывая нужный бит в 1 MIXER((s-1)*SB_SAMPLE); //декодирование одного фрейма декодера в нужную половину буфера + микширование с другими звуковыми выборками } } Стало так: void __attribute__ ((interrupt ("IRQ"))) irq_handler(void) { s=DMA_IRQ_PEND_STAS_REG&3; if(s) { DMA_IRQ_PEND_STAS_REG|=s; //подтверждение нужногопрерывания sound_flag=1; //флаг =1 когда можно грузить новые данные } } //Основной цикл программы: int main(void) { while(1) //вечный цикл { while(!sound_flag); //ждём пока sound_flag станет =1, чтобы подгрузить новые данные в нужную половину буфера sound_flag=0; //обнуляем до следующего раза MIXER((s-1)*SB_SAMPLE); //подгружаем новые данные } return 0; //чистая формальность для C++ } Недостаток второго способа в том, что если в программе что-то будет делаться ещё, и оно превысит время воспроизведения одной половины, то звук будет рваным. Идеально декод фрейма пихать в обработчик, получается всегда идеально-непрерывное воспроизведение звука. В DSP C6745 номально работает декод в обработчике прерывания - успевает и не вылетает из-за вложенного прерывания. А в A13 явно всё тухло... Или я их пока ещё не раскурил? По DMA, тоже не всё гладко. ДМА работает если память источника и приёмника не кешируема. Если хоть какой-то регион будет кешируемым, то даже Flush Data Cache не спасает - ДМА просто не стартует. А это - "ОЙ"! Так как мне нужен кешируемый участок памяти, так как я его ещё читаю (нужно вычитывать отдельные пикселы для проверки), так что буферизация на запись - спасает только при записи. В общем, вывод такой. Если сравнивать A13 и C6745, то последний однозначно более дружественен к игровым приложениям. Я уже молчу о том, что драйвера sunxi-linux кривые настолько, что китайцы не различают - взятие адреса и само значение переменной, что часто приводило к вылету на эксепшн Abort или Undef. P.S. Скачал armclang, входящий в состав ARM Development Studio - у них 90-дневная проба со всеми возможностями из-за ковида, потестил его. В случае С++ - программа не стартует вообще! Опять намудрили что-то... В GCC всё стартует. А теперь цены: A13 - за 450 р и C6745 за 2500 р. У первого всё через одно место (включая поддержку софтов), в во втором всё по-человечески сделано. Финита ля комедия Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 2 27 мая, 2020 Опубликовано 27 мая, 2020 · Жалоба Так об этом еще А.С.Пушкин писал... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 27 мая, 2020 Опубликовано 27 мая, 2020 (изменено) · Жалоба 1 час назад, __inline__ сказал: А теперь цены: A13 - за 450 р и C6745 за 2500 р. У первого всё через одно место (включая поддержку софтов), в во втором всё по-человечески сделано. Это вполне норм. Еррату на А13 видели? Нет, потому, что ее никто не сделал или нет в открытом доступе, на техасовский ДСП она есть наверняка, только вот печаль в том, что А13 тоже далеко не безупречен, особенно в тех режимах, которые вы используете, вот такое и выстреливает порой... К счастью сам использовал видимо все это дело в обычных режимах, где работает все, что мне надо... На счет прерываний - в А13 стоит очень упрощенный контроллер, в более поздних аллвиннерах используют GIC, но это все тоже мне не нравится, т.к. векторный сепаратор нужно делать программный, в отличии от М серии... Изменено 27 мая, 2020 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 27 мая, 2020 Опубликовано 27 мая, 2020 (изменено) · Жалоба 2 hours ago, mantech said: только вот печаль в том, что А13 тоже далеко не безупречен, особенно в тех режимах, которые вы используете, вот такое и выстреливает порой... К счастью сам использовал видимо все это дело в обычных режимах, где работает все, что мне надо... Я тут почитал доки на ARM MMU, с целью узнать назначение кое-каких битов в дескрипторах. Интересным образом повело себя битовое поле TEX[14:12]. Если его установить в "001", и установить бит B (buffer), кеш (C) сбросить, то получиться прирост в скорости отрисовки. Источник: C=1, B=1, TEX=0. Приёмник C=0, B=1, TEX=001. В 1,5 раза быстрее , чес в случае с приёмником C=0, B=1, TEX=000. 2 hours ago, mantech said: На счет прерываний - в А13 стоит очень упрощенный контроллер, в более поздних аллвиннерах используют GIC, но это все тоже мне не нравится, т.к. векторный сепаратор нужно делать программный, в отличии от М серии... Всегда стараюсь в последнюю очередь думать плохо о вендоре и в первую очередь всегда полагаю, что "я сам дурак". Поэтому ещё пока уделю A13 время. Но исходя по опыту, по поводу Allwinner: 1) драйвера linux-sunxi кривые. В mmc.c в функции int mmc_startup(struct mmc *mmc) есть такая строка: memcpy(mmc->cid, cmd.response, 16); Это неверно. И приводит к неверной записи результата в приёмник. Надо так: memcpy(mmc->cid, &cmd.response, 16); И там такого полно 2) нету штатной среды разработки. Тут только gcc arm-none-eabi, который на сложном коде генерирует нерабочий бинарник (программа повисает в середине работы). Или armclang v.6 из ARM Studio (платный). 3) Само железо не очень дружественно. В C6745 многие вещи делаются намного красивее и проще. Те же прерывания. В C6745 можно присвоить любой вектор прерывания любому источнику прерывания. И выделенный вектор на свой источник прерывания! 4) Программная модель Cortex-A8 смотрится как-то тухло по сравнению с C6000+. Одиночные команды, меньший регистровый файл, отсутствие параллельности выполения кода. Нет сопроцессоров, которые могли бы делать какие-то примитивные, но нужные вещи (типа ожидать VSYNC, а потом рисовать кадр, при этом не тормозя ожиданием основной процессор, который синхронизируется от второго источника). Наглядный пример: параллельная синхронизация по видео(сопроцессор) и по звуку (основной процессор). Пока не получается его загрузиь по-полной. Нужно построить фрейм в буфере, состоящего из спрайтов (при этом буфер должен читаться, чтобы определять цвет пикселей), затем по VSYNC его передать на дисплей. При этом играет аудио - 12 каналов WAV PCM (звуки) + 1 канал музыки (декодер OPUS) . Плюс к тому же опрос управления с кейпада. В C6745 эта задача успешно решена так: - рендеринг кадра: DSP. Подкачка данных и декодирование звука - в обработчике прерывания. - синхронизация видео, отрисовка кадра - встроенный сопроцессор PRU1 - опрос кнопок (с нестандартного девайса, где нужно точно выдержать задержки по сигналам) - второй встроенный сопроцессор PRU2 При этом память гибко конфигурируется: это кеши L1 под код-данные или часть из них пускается под быстрые буфера. При этом их кеширование не нужно! Память L2 - распиливается аналогично: часть используем как кеш L2, а часть на видео-буфер. Внешняя память - код + данные: закеширована. В A13 не так много внутренней памяти, хотябы чтоб создать 400x240 16 бит на точку. Приходится всё тулить в медленную DDR, которая кешируется или нет. Не удобно! Посмотрим ещё... Пока выходит что C6000+ @456 MHz + 2 x RISC PRU @ 228 MHz + SDRAM 16bit @ 152 MHz - лучше, чем Cortex-A8 @960 MHz + DDR3 16 bit @408 MHz Изменено 27 мая, 2020 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 27 мая, 2020 Опубликовано 27 мая, 2020 (изменено) · Жалоба 1 час назад, __inline__ сказал: Посмотрим ещё... Пока выходит что C6000+ @456 MHz + 2 x RISC PRU @ 228 MHz + SDRAM 16bit @ 152 MHz - лучше, чем Cortex-A8 @960 MHz + DDR3 16 bit @408 MHz С вашими задачами не знаком (игры - не мое))) ), но просто представил разрешение 400x240, сравнил его со своей задачей (1366х768х32 2 слоя), плюс 3х канальный парсер многопоточных вирт. задач, графический интерфейс (в текущей задаче 17 форм из которых 3-4 постоянно на экране), плюс к этому должен работать сетевой стек (прием отправка пакетов на удаленный сервер), ну и по мелочи - работа с тачпанелью, картридером RFID, УАРТом на 115200 в постоянной загрузке... проц с тормозной памятью (IMX6-800МГц) и все вроде успевает.... Может что-то еще у вас есть не оптимального? Изменено 27 мая, 2020 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 27 мая, 2020 Опубликовано 27 мая, 2020 · Жалоба 32 minutes ago, mantech said: Может что-то еще у вас есть не оптимального? На C6745 всё превосходно работает и на меньших частотах. 33 minutes ago, mantech said: но просто представил разрешение 400x240, сравнил его со своей задачей ... Я не договорил Ещё вдовесок к вышесказанному: 1) физический движок Box2D на плавучке 2) декодирование Opus 3) распаковка ZLIB 4) логика игры 5) свой графический API (рисование спрайтов с полу-прозрачностью, поворотом, отражением, перестановкой компонент, ....) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 27 мая, 2020 Опубликовано 27 мая, 2020 (изменено) · Жалоба Удалось всё-же запустить декодирование в обработчике прерывания. Подтверждать прерывание надо ПОСЛЕ декодирования, а не ДО-: void __attribute__ ((interrupt ("IRQ"))) irq_handler(void) { s=DMA_IRQ_PEND_STAS_REG&3; if(s) { MIXER((s-1)*SB_SAMPLE); //декодирование DMA_IRQ_PEND_STAS_REG|=s; //подтверждение } } Теперь осталось решить другую проблему. Если в цикле программы что-нибудь выполнить, то декодирование срывается и программа вылетает в Undef. Если цикл оставить пустой, то декодирование работает. Что за издевательство? Сильно похоже на конфликт за общую память. Память внешняя, в ней код, данные. Работает ДМА и отображение кадра видео. Изменено 27 мая, 2020 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 28 мая, 2020 Опубликовано 28 мая, 2020 (изменено) · Жалоба 9 hours ago, __inline__ said: Теперь осталось решить другую проблему. Если в цикле программы что-нибудь выполнить, то декодирование срывается и программа вылетает в Undef. Если цикл оставить пустой, то декодирование работает. Что за издевательство? Сильно похоже на конфликт за общую память. Память внешняя, в ней код, данные. Работает ДМА и отображение кадра видео. Проблема успешно решена! Вначале вставил задержку в обработчике прерывания на несколько милли-секунд, подтвердив прерывание в конце. Увидев, что в обработчике можно находиться времени ещё больше, чем время декодирования, сообразил, что причина зависания не в "большой" задержке выполнения кода, а в самой функции декодирования фрейма. С другой стороны, известно, что та самая функция декодирования отлично пашет в главном цикле программы.... И тут пришло озарение. Экспешены Abort/Undef сыпались из-за недостаточного количества стека в режиме IRQ! Очевидно, функция декодирования фрейма использует достаточное число стека, так как глубина вложенности остальных функций в ней достаточно приличная. Увеличил стек для прерываний : было 256 байт, поставил 64K: .set UND_STACK_SIZE, 0x100 .set ABT_STACK_SIZE, 0x100 .set FIQ_STACK_SIZE, 0x100 .set IRQ_STACK_SIZE, 0x10000 .set SVC_STACK_SIZE, 0x10000 .set MODE_USR, 0x10 .set MODE_FIQ, 0x11 .set MODE_IRQ, 0x12 .set MODE_SVC, 0x13 .set MODE_ABT, 0x17 .set MODE_UND, 0x1B .set MODE_SYS, 0x1F .equ I_F_BIT, 0xC0 LDR r0, =_stack @ Read the stack address MSR cpsr_c, #MODE_UND|I_F_BIT @ switch to undef mode MOV sp,r0 @ write the stack pointer SUB r0, r0, #UND_STACK_SIZE @ give stack space @ @ Set up the Stack for abort mode @ MSR cpsr_c, #MODE_ABT|I_F_BIT @ Change to abort mode MOV sp, r0 @ write the stack pointer SUB r0,r0, #ABT_STACK_SIZE @ give stack space @ @ Set up the Stack for FIQ mode @ MSR cpsr_c, #MODE_FIQ|I_F_BIT @ change to FIQ mode MOV sp,r0 @ write the stack pointer SUB r0,r0, #FIQ_STACK_SIZE @ give stack space @ @ Set up the Stack for IRQ mode MSR cpsr_c, #MODE_IRQ|I_F_BIT @ change to IRQ mode MOV sp,r0 @ write the stack pointer SUB r0,r0, #IRQ_STACK_SIZE @ give stack space @ @ Set up the Stack for SVC mode @ MSR cpsr_c, #MODE_SVC|I_F_BIT @ change to SVC mode MOV sp,r0 @ write the stack pointer SUB r0,r0, #SVC_STACK_SIZE @ give stack space @ @ Set up the Stack for USer/System mode @ MSR cpsr_c, #MODE_SYS|I_F_BIT @ change to system mode MOV sp,r0 @ write the stack pointer Сам обработчик прерывания - часть на C: void IRQ_HANDLER(void) { u32 icchpir=GICC_HPPIR; //байда для Cortex-A8 u32 icciar =GICC_IAR; u32 s=DMA_IRQ_PEND_STAS_REG&3; //проверяем что прерывание от DMA (half-(s=1) и full-(s=2) transfer) if(s) { MIXER((s-1)*SB_SAMPLE); //декодируем фрейм в нужную половину буфера ToggleLED //включение-выключение светодиода (мониторинг) DMA_IRQ_PEND_STAS_REG|=s; //подтверждаем прерывание } GICC_EOIR=icciar&0x1FFF; //байда для Cortex-A8 } Обработчик прерывания на ASM (в нём дёргается код выше) - для сохранения-восстановления нужных регистров(при входе-выходе в/из прерывания): IRQHandler: sub lr, lr, #4 stmfd sp!, {lr} mrs lr, SPSR stmfd sp!, {r0, lr} stmfd sp!, {r0-r3, r4, r12, lr} ldr r2, =IRQ_HANDLER mov lr, pc bx r2 ldmia sp!, {r0-r3, r4, r12, lr} ldmia sp!, {r0, lr} msr SPSR_cxsf, lr ldmia sp!, {pc}^ Последние два фрагмента позаимствованы у @GenaSPB, из темы: за что ему большое спасибо! Хотя, можно было ограничиться вот этим (без реализации вложенного прерывания) на манер синтаксиса GCC: void __attribute__ ((interrupt ("IRQ"))) IRQ_HANDLER(void) { u32 icchpir=GICC_HPPIR; u32 icciar =GICC_IAR; u32 s=DMA_IRQ_PEND_STAS_REG&3; if(s) { MIXER((s-1)*SB_SAMPLE); ToggleLED DMA_IRQ_PEND_STAS_REG|=s; } GICC_EOIR=icciar&0x1FFF; } Так что в принципе я зря катил бочку на A13, так как я совсем позабыл, что в прерывании у ARM стек свой отдельно. А вот для чего нужны __DSB() и __ISB()? Кто может рассказать? :) Изменено 28 мая, 2020 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 28 мая, 2020 Опубликовано 28 мая, 2020 · Жалоба 1 hour ago, __inline__ said: А вот для чего нужны __DSB() и __ISB()? Кто может рассказать? :) Это барьерные операции. Они гарантируют, что следующие за ней операции не будут начаты, пока не завершатся эти операции. Собственно, лучше будет, если вы скажете, какое именно из предложений здесь http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html вам не понятно, чтобы понимать, начинать объяснение от Адама и Евы, или всё-таки поближе к программированию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 28 мая, 2020 Опубликовано 28 мая, 2020 · Жалоба 3 hours ago, one_eight_seven said: Это барьерные операции. Они гарантируют, что следующие за ней операции не будут начаты, пока не завершатся эти операции. Собственно, лучше будет, если вы скажете, какое именно из предложений здесь http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html вам не понятно, чтобы понимать, начинать объяснение от Адама и Евы, или всё-таки поближе к программированию. Ваше объяснение мне более симпатично, чем на сайте arm.com. То о чём они пишут, приходится многокоратно перечитывать, чтобы понять смысл. Ещё более тяжелее представить ситуацию, где это действительно необходимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 28 мая, 2020 Опубликовано 28 мая, 2020 · Жалоба 8 minutes ago, __inline__ said: Ваше объяснение мне более симпатично, чем на сайте arm.com. То о чём они пишут, приходится многокоратно перечитывать, чтобы понять смысл. Ещё более тяжелее представить ситуацию, где это действительно необходимо. Где необходимо? Там, где нужна синхронизация при работе с данными/инструкциями. Наприме ISB - гарантирует, что операции, которые следуют после этой инструкции не будут считаны из памяти, пока не выполнится ISB. Пример - включаете NEON или другой сопроцессор, и с помощью ISB гарантируете, что опкоды сопроцессора не будут считываться из памяти, пока сопроцессор не будет включён. DMB - это для работы с данными. Нужно, чтобы все мастера увидели все все данные, прежде, чем новые данные будут записаны в память или считаны из неё. Например, при работе с MMU или инвалидацией кэша. DSB - как DMB, только распространяется на все инструкции, а не только на семейство ST/LD Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 29 мая, 2020 Опубликовано 29 мая, 2020 · Жалоба 22 hours ago, one_eight_seven said: Там, где нужна синхронизация при работе с данными/инструкциями. Спасибо за исчерпывающий ответ! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 3 июня, 2020 Опубликовано 3 июня, 2020 · Жалоба Обнаружил глюк GCC. Собирал кодек CELT на максимальной оптимизации. Кодек работал пару секунд и завешивал CPU в Abort. В ходе копаний(понижая постепенно оптимизацию модулям кодека ) выяснил модуль-виновник, а позже - функцию-виновник, вызывающую зависание. Вот сама функция: Spoiler Quote int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, int alloc_trim, int total, int *pulses, int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev) { int lo, hi, len, j; const int C = CHANNELS(_C); int codedBands; int skip_start; int skip_rsv; VARDECL(int, bits1); VARDECL(int, bits2); VARDECL(int, thresh); VARDECL(int, trim_offset); SAVE_STACK; total = IMAX(total, 0); len = m->nbEBands; skip_start = start; /* Reserve a bit to signal the end of manually skipped bands. */ skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0; total -= skip_rsv; ALLOC(bits1, len, int); ALLOC(bits2, len, int); ALLOC(thresh, len, int); ALLOC(trim_offset, len, int); for (j=start;j<end;j++) { /* Below this threshold, we're sure not to allocate any PVQ bits */ thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4); /* Tilt of the allocation curve */ trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)<<(LM+BITRES)>>6; /* Giving less resolution to single-coefficient bands because they get more benefit from having one coarse value per coefficient*/ if ((m->eBands[j+1]-m->eBands[j])<<LM==1) trim_offset[j] -= C<<BITRES; } lo = 1; hi = m->nbAllocVectors - 2; do { int done = 0; int psum = 0; int mid = (lo+hi) >> 1; for (j=end;j-->start;) { int N = m->eBands[j+1]-m->eBands[j]; bits1[j] = C*N*m->allocVectors[mid*len+j]<<LM>>2; if (bits1[j] > 0) bits1[j] = IMAX(0, bits1[j] + trim_offset[j]); bits1[j] += offsets[j]; if (bits1[j] >= thresh[j] || done) { done = 1; /* Don't allocate more than we can actually use */ psum += IMIN(bits1[j], 64*C<<BITRES<<LM); } else { if (bits1[j] >= C<<BITRES) psum += C<<BITRES; } } if (psum > total) hi = mid - 1; else lo = mid + 1; /*printf ("lo = %d, hi = %d\n", lo, hi);*/ } while (lo <= hi); hi = lo--; /*printf ("interp between %d and %d\n", lo, hi);*/ for (j=start;j<end;j++) { int N = m->eBands[j+1]-m->eBands[j]; bits1[j] = C*N*m->allocVectors[lo*len+j]<<LM>>2; bits2[j] = C*N*m->allocVectors[hi*len+j]<<LM>>2; if (bits1[j] > 0) bits1[j] = IMAX(0, bits1[j] + trim_offset[j]); if (bits2[j] > 0) bits2[j] = IMAX(0, bits2[j] + trim_offset[j]); if (lo > 0) bits1[j] += offsets[j]; bits2[j] += offsets[j]; if (offsets[j]>0) skip_start = j; bits2[j] -= bits1[j]; } codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, total, skip_rsv, pulses, ebits, fine_priority, len, C, LM, ec, encode, prev); RESTORE_STACK; return codedBands; } Вывывает зависание вот эта строка: trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)<<(LM+BITRES)>>6; Если сделать так: volatile int TEMP=C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)<<(LM+BITRES)>>6; trim_offset[j]=TEMP; Или так: trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)<<(LM+BITRES)>>6; asm volatile("": : :"memory"); То кодек работает без зависаний и на -O3 , -Ofast. Без этих ухищрений работает только на -O0, -O1. Подозреваю, что приведённые выше меры позволяют изменить последовательность команд при ассемблировании и избежать ошибок билда GCC. Тулчейн : gcc-arm-none-eabi 9-2019-q4-major P.S. Этот же код собирается под ПК(mingw) и C6000+(TI compilet 8.3.5) и работает без переделок. Вопрос- почему? Можно ли доверять GCC сложные проекты (по сотни тысяч строк кода) после этого? P.P.S. Попутно вылезают неожиданные результаты из-за типкаста занковое-беззнаковое или наоборот. Пример: s32 x = floor(((amp->x * TO_GFX_SCALE) - ((float)amp->mp->width * 0.5f) - (float)cameraX) + 0.5f); s32 y = floor(((amp->y * TO_GFX_SCALE) - ((float)amp->mp->height * 0.5f) - (float)cameraY) + 0.5f); - даёт неверный результат на GCC. На TI, ПК этот код работает корректно! Но если сделать так: s32 x = (s32)floor(((amp->x * TO_GFX_SCALE) - ((float)amp->mp->width * 0.5f) - (float)cameraX) + 0.5f); s32 y = (s32)floor(((amp->y * TO_GFX_SCALE) - ((float)amp->mp->height * 0.5f) - (float)cameraY) + 0.5f); - то работает корректно везде и на GCC. Знающие, разъясните, почему такое имеет место быть? Порядок типкаста отличается или как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 4 июня, 2020 Опубликовано 4 июня, 2020 · Жалоба 10 hours ago, __inline__ said: Подозреваю, что приведённые выше меры позволяют изменить последовательность команд при ассемблировании и избежать ошибок билда GCC. Тулчейн : gcc-arm-none-eabi 9-2019-q4-major Глянул листинги. так и есть. Кроме volatile, барьера, можно ещё asm'овый NOP вставить - результат тоже будет положительным. Ход выстраивания команд отличается. Вот рабочий вариант с NOP'ом: Spoiler .section .text.compute_allocation,"ax",%progbits .align 2 .global compute_allocation .syntax unified .arm .fpu neon .type compute_allocation, %function compute_allocation: @ args = 40, pretend = 0, frame = 120 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, r5, r6, r7, r8, r9, r10, fp, lr} sub sp, sp, #124 movw lr, #:lower16:global_stack movt lr, #:upper16:global_stack ldr ip, [sp, #164] str r2, [sp, #16] ldr r2, [r0, #8] cmp ip, #7 str r3, [sp, #104] bic r3, ip, ip, asr #31 str r3, [sp, #12] subgt r3, r3, #8 str r2, [sp, #60] movle r3, #0 ldr r2, [lr] strgt r3, [sp, #12] movgt r3, #8 str r3, [sp, #112] rsb r7, r2, #0 ldr r3, [sp, #60] and r7, r7, #3 str r0, [sp, #24] mov r0, r1 str r1, [sp, #20] lsl r3, r3, #2 ldr r1, [sp, #16] str r2, [sp, #88] add r2, r2, r7 str r2, [sp, #76] add r2, r2, r3 cmp r0, r1 rsb r1, r2, #0 and r1, r1, #3 str lr, [sp, #92] add r2, r2, r1 str r2, [sp, #96] add r2, r2, r3 ldrd r10, [sp, #180] rsb r8, r2, #0 and r8, r8, #3 add r8, r2, r8 add r1, r8, r3 rsb r2, r1, #0 and r2, r2, #3 add r1, r1, r2 ldr r2, [sp, #92] add r3, r1, r3 str r1, [sp, #100] str r3, [r2] bge .L74 ldr r9, [sp, #24] mov r2, r0 ldr r3, [sp, #160] lsl r0, r0, #2 add lr, r1, r0 lsl r1, r10, #3 sub r5, r3, #5 ldr r3, [r9, #24] sub r5, r5, fp add r6, fp, #3 add r4, r8, r0 str r8, [sp] mov r8, r1 str r0, [sp, #84] str r1, [sp, #8] .L76: add r7, r2, #1 lsl r0, r7, #1 sub ip, r0, #2 ldrsh r1, [r3, r0] ldrsh r3, [r3, ip] sub r3, r1, r3 mul r1, r10, r3 add r3, r3, r3, lsl #1 lsl r3, r3, fp sbfx r3, r3, #1, #28 cmp r3, r8 mul r1, r5, r1 movlt r3, r8 str r3, [r4], #4 ldr r3, [r9, #8] sub r2, r3, r2 sub r2, r2, #1 mul r1, r1, r2 lsl r1, r1, r6 asr r1, r1, #6 str r1, [lr], #4 .syntax divided @ 569 "CELT/rate.c" 1 nop @ 0 "" 2 .arm .syntax unified ldr r3, [r9, #24] mov r2, r7 ldrsh r1, [r3, r0] ldrsh r0, [r3, ip] sub r1, r1, r0 lsl r1, r1, fp cmp r1, #1 ldreq r1, [lr, #-4] subeq r1, r1, r8 streq r1, [lr, #-4] ldr r1, [sp, #16] cmp r1, r7 bne .L76 ldr r8, [sp] str r3, [sp, #80] .L77: ldr r3, [sp, #24] lsl r0, r10, #9 lsl r2, r1, #2 ldr r4, [sp, #20] sub ip, r1, #1 str r0, [sp, #108] ldr r3, [r3, #28] lsl lr, r4, #1 str ip, [sp, #56] sub r3, r3, #2 str r3, [sp, #32] lsl r3, r0, fp str r3, [sp] add r3, r8, r2 str r3, [sp, #4] ldr r3, [sp, #76] str r2, [sp, #72] add r3, r3, r2 str r3, [sp, #48] ldr r3, [sp, #104] str lr, [sp, #52] add r3, r3, r2 str r3, [sp, #64] ldr r3, [sp, #100] str ip, [sp, #44] add r3, r3, r2 str r3, [sp, #68] ldr r3, [sp, #80] str r4, [sp, #116] add r9, lr, r3 add r3, r3, r1, lsl #1 str r3, [sp, #40] mov r3, #1 str r3, [sp, #28] .L86: ldrd r2, [sp, #16] cmp r3, r2 ldrd r2, [sp, #28] add r3, r3, r2 asr r3, r3, #1 str r3, [sp, #36] bge .L138 ldr r1, [sp, #56] mov r7, #0 ldr r2, [sp, #60] mov r4, r7 ldr lr, [sp, #68] ldr r6, [sp, #4] mla ip, r3, r2, r1 ldr r3, [sp, #24] ldr r5, [sp, #64] ldr r0, [sp, #48] ldr r3, [r3, #32] add ip, ip, #1 ldr r1, [sp, #40] add ip, r3, ip b .L82 .L170: ldr r2, [sp] sub lr, lr, #4 cmp r3, r2 addle r7, r7, r3 addgt r7, r7, r2 cmp r1, r9 beq .L78 .L82: ldrsh r2, [r1] ldrsh r8, [r1, #-2]! ldrb r3, [ip, #-1]! @ zero_extendqisi2 sub r2, r2, r8 mul r2, r10, r2 mul r3, r3, r2 lsl r3, r3, fp asr r3, r3, #2 str r3, [r0, #-4]! cmp r3, #0 ldrgt r2, [lr, #-4] addgt r3, r3, r2 bicgt r3, r3, r3, asr #31 strgt r3, [r0] ldr r2, [r5, #-4]! add r3, r3, r2 str r3, [r0] ldr r2, [r6, #-4]! cmp r3, r2 movlt r2, r4 orrge r2, r4, #1 mov r4, #1 cmp r2, #0 bne .L170 ldr r8, [sp, #8] sub lr, lr, #4 mov r4, r2 cmp r3, r8 addge r7, r7, r8 cmp r1, r9 bne .L82 .L78: ldr r3, [sp, #12] cmp r7, r3 ldr r3, [sp, #36] ble .L83 ldr r2, [sp, #28] sub r3, r3, #1 str r3, [sp, #32] cmp r2, r3 ble .L86 .L85: ldr r3, [sp, #16] ldr ip, [sp, #20] cmp ip, r3 ldr r3, [sp, #28] sub r7, r3, #1 bge .L140 ldr lr, [sp, #60] mov r6, ip ldr r2, [sp, #24] ldr r1, [sp, #84] mul r3, r7, lr ldr r0, [sp, #104] ldr r2, [r2, #32] ldr r5, [sp, #96] add r4, r0, r1 add lr, r3, lr ldr r0, [sp, #76] add r3, r3, ip add lr, lr, ip str r7, [sp, #28] add r0, r0, r1 ldr r7, [sp, #100] add r1, r5, r1 add lr, r2, lr add r5, r2, r3 .L93: mov r2, r9 ldrsh r3, [r9, #2] ldrsh r8, [r2] add r9, r9, #2 ldrb r2, [r5], #1 @ zero_extendqisi2 sub r3, r3, r8 mul r3, r10, r3 mul r2, r3, r2 lsl r2, r2, fp asr r2, r2, #2 str r2, [r0] ldrb r2, [lr], #1 @ zero_extendqisi2 mul r3, r3, r2 lsl r3, r3, fp asr r3, r3, #2 str r3, [r1], #4 ldr r2, [r0], #4 cmp r2, #0 ldrgt r3, [r7, ip, lsl #2] addgt r3, r3, r2 bicgt r3, r3, r3, asr #31 strgt r3, [r0, #-4] ldrgt r3, [r1, #-4] cmp r3, #0 ldrgt r2, [r7, ip, lsl #2] addgt r3, r3, r2 ldr r2, [sp, #28] bicgt r3, r3, r3, asr #31 strgt r3, [r1, #-4] cmp r2, #0 ldrgt r3, [r0, #-4] ldrgt r2, [r4] addgt r3, r3, r2 strgt r3, [r0, #-4] ldr r2, [r4] ldrgt r3, [r1, #-4] add r3, r3, r2 str r3, [r1, #-4] ldr r8, [r4], #4 ldr r2, [r0, #-4] cmp r8, #0 ldr r8, [sp, #40] sub r3, r3, r2 str r3, [r1, #-4] movgt r6, ip cmp r9, r8 add ip, ip, #1 bne .L93 str r6, [sp, #28] .L87: ldr r3, [sp, #96] cmp r10, #1 ldr r2, [sp, #72] mov r8, #0 str r10, [sp, #180] add r9, r3, r2 ldr r3, [sp, #76] ldr r2, [sp, #84] str r9, [sp, #32] ldr r10, [sp, #8] add r7, r3, r2 ldr r9, [sp] movle r3, #0 movgt r3, #1 str r3, [sp, #60] mov r3, #6 str r3, [sp, #36] mov r3, #64 str fp, [sp, #184] mov fp, r3 .L99: ldrd r2, [sp, #16] add r6, r8, fp mov r4, #0 cmp r3, r2 asr r6, r6, #1 bge .L94 ldr lr, [sp, #4] mov r0, r4 ldr ip, [sp, #32] ldr r1, [sp, #48] b .L97 .L171: cmp r9, r3 addle r4, r4, r9 addgt r4, r4, r3 cmp r7, r1 beq .L94 .L97: ldr r5, [ip, #-4]! ldr r3, [r1, #-4]! ldr r2, [lr, #-4]! mul r5, r5, r6 add r3, r3, r5, asr #6 cmp r2, r3 movgt r2, r0 orrle r2, r0, #1 mov r0, #1 cmp r2, #0 bne .L171 cmp r10, r3 mov r0, r2 addle r4, r4, r10 cmp r7, r1 bne .L97 .L94: ldr r3, [sp, #12] cmp r4, r3 ldr r3, [sp, #36] movgt fp, r6 movle r8, r6 subs r3, r3, #1 str r3, [sp, #36] bne .L99 ldrd r2, [sp, #16] ldr r9, [sp, #32] cmp r3, r2 ldrd r10, [sp, #180] bge .L144 ldr r3, [sp, #108] ldr r0, [sp, #36] ldr r2, [sp, #72] lsl ip, r3, fp ldr r3, [sp, #168] ldr lr, [sp, #4] mov r5, r0 ldr r6, [sp, #48] add r4, r3, r2 b .L102 .L101: cmp ip, r3 movlt r3, ip cmp r6, r7 add r5, r5, r3 str r3, [r4, #-4]! beq .L172 .L102: ldr r1, [r9, #-4]! eor r2, r0, #1 ldr r3, [r6, #-4]! mov r0, #1 ldr r10, [lr, #-4]! mul r1, r1, r8 add r3, r3, r1, asr #6 cmp r10, r3 movle r2, #0 andgt r2, r2, #1 cmp r2, #0 beq .L101 ldr r2, [sp, #8] mov r0, #0 cmp r2, r3 mov r3, r0 movle r3, r2 b .L101 .L83: ldr r2, [sp, #32] add r3, r3, #1 str r3, [sp, #28] cmp r2, r3 bge .L86 b .L85 .L138: mov r7, #0 b .L78 .L172: ldr r3, [sp, #12] ldr r10, [sp, #180] sub r0, r3, r5 .L100: ldr r3, [sp, #40] ldr r2, [sp, #52] ldrsh r4, [r3] ldr r3, [sp, #80] ldrsh r9, [r3, r2] sub r1, r4, r9 bl __aeabi_idivmod ldr r3, [sp, #28] ldr r2, [sp, #56] cmp r3, r2 mov r6, r1 str r0, [sp, #40] bge .L173 ldr r3, [sp, #8] ldr r2, [sp, #72] add r3, r3, #8 str r3, [sp] ldr r3, [sp, #168] str r10, [sp, #180] mov r10, r9 add r7, r3, r2 ldr r8, [sp, #44] ldr r2, [sp, #40] ldr r9, [sp, #80] str fp, [sp, #184] b .L105 .L176: ldr r3, [sp, #196] cmp r3, r8 movgt r3, #7 movle r3, #9 mul lr, r3, lr ldr r3, [sp, #184] lsl lr, lr, r3 sbfx lr, lr, #1, #28 cmp r4, lr bgt .L174 ldr r0, [sp, #188] mov r2, #1 mov r1, #0 bl ec_enc_bit_logp .L111: ldr r3, [sp, #24] add r5, r5, #8 ldr ip, [r7] sub r4, r4, #8 ldr r9, [r3, #24] ldr r3, [sp, #52] ldrsh r10, [r9, r3] .L107: ldr r3, [sp, #8] sub r5, r5, ip cmp r4, r3 addge r5, r5, r3 movge r2, r3 movlt r2, #0 .L112: ldrsh r4, [r9, fp] sub fp, r8, #1 ldr r3, [sp, #12] str r2, [r7] sub r1, r4, r10 sub r0, r3, r5 bl __aeabi_idivmod ldr r3, [sp, #28] cmp fp, r3 mov r2, r0 mov r6, r1 beq .L175 mov r8, fp .L105: lsl fp, r8, #1 ldr r3, [sp, #4] ldr ip, [r7, #-4]! ldrsh r1, [r9, fp] ldr r0, [r3, #-4]! sub lr, r4, r1 sub r1, r1, r10 sub r1, r6, r1 mla r4, r2, lr, ip str r3, [sp, #4] add r3, r8, #1 str r3, [sp, #32] ldr r3, [sp] cmp r1, #0 addge r4, r4, r1 cmp r3, r0 movge r0, r3 cmp r4, r0 blt .L107 ldr r3, [sp, #192] cmp r3, #0 bne .L176 ldr r0, [sp, #188] mov r1, #1 str r2, [sp, #40] bl ec_dec_bit_logp ldr r2, [sp, #40] cmp r0, #0 beq .L111 ldr r3, [sp, #32] str r2, [sp, #40] ldr r2, [sp, #20] str r3, [sp, #44] ldr r1, [sp, #44] ldrd r10, [sp, #180] cmp r2, r1 blt .L177 .L113: ldr r3, [sp, #16] ldr r2, [sp, #20] cmp r3, r2 ble .L133 ldr r3, [sp, #56] add r1, r2, #4 mov r6, r2 ldr r0, [sp, #176] sub r5, r3, r2 ldr r2, [sp, #168] lsl r1, r1, #2 add lr, r2, r1 ldr r2, [sp, #172] sub r3, r1, #16 add ip, r2, r3 ldr r2, [sp, #168] add r2, r2, r3 add r3, r0, r3 ldr r0, [sp, #172] add r4, r0, r1 ldr r0, [sp, #176] cmp r2, r4 cmpcc ip, lr add r1, r0, r1 movcs r0, #1 movcc r0, #0 cmp r2, r1 cmpcc r3, lr movcs lr, #1 movcc lr, #0 cmp r3, r4 cmpcc ip, r1 and lr, lr, r0 movcs r1, #1 movcc r1, #0 cmp r5, #3 movls lr, #0 andhi lr, lr, #1 ands r1, lr, r1 beq .L130 ldr r1, [sp, #16] vmov.i32 q9, #0 @ v4si vmov.i32 q11, #1 @ v4si sub r5, r1, r6 ldr r1, [sp, #60] lsr r4, r5, #2 vdup.32 q10, r1 ldr r1, [sp, #36] lsl r4, r4, #4 vneg.s32 q10, q10 .L131: add lr, r2, r1 add r0, ip, r1 add r6, r3, r1 add r1, r1, #16 vld1.32 {q8}, [lr] cmp r4, r1 vshl.s32 q8, q8, q10 vshr.s32 q8, q8, #3 vst1.32 {q8}, [r0] vst1.32 {q9}, [lr] vld1.32 {q8}, [r0] vcle.s32 q8, q8, #0 vbsl q8, q11, q9 vst1.32 {q8}, [r6] bne .L131 bic r3, r5, #3 ldr r2, [sp, #20] cmp r3, r5 add r3, r3, r2 beq .L133 ldr r2, [sp, #168] mov r0, #0 ldr lr, [sp, #60] add ip, r3, #1 ldr r4, [sp, #172] ldr r1, [r2, r3, lsl #2] lsl r2, r3, #2 asr r1, r1, lr asr r1, r1, #3 str r1, [r4, r3, lsl #2] ldr r1, [sp, #168] str r0, [r1, r3, lsl #2] ldr r1, [r4, r3, lsl #2] ldr r4, [sp, #16] cmp r1, r0 movgt r1, #0 movle r1, #1 cmp r4, ip ldr ip, [sp, #176] str r1, [ip, r3, lsl #2] ble .L133 ldr ip, [sp, #168] add r1, r2, #4 ldr r5, [sp, #172] add r3, r3, #2 ldr ip, [ip, r1] asr ip, ip, lr asr ip, ip, #3 str ip, [r5, r1] ldr ip, [sp, #168] str r0, [ip, r1] ldr ip, [r5, r1] cmp ip, r0 movgt ip, #0 movle ip, #1 cmp r4, r3 ldr r3, [sp, #176] str ip, [r3, r1] ble .L133 add r3, r2, #8 ldr r2, [sp, #168] ldr r1, [sp, #176] ldr r2, [r2, r3] asr r2, r2, lr asr r2, r2, #3 str r2, [r5, r3] ldr r2, [sp, #168] str r0, [r2, r3] ldr r2, [r5, r3] cmp r2, r0 movgt r2, #0 movle r2, #1 str r2, [r1, r3] .L133: ldrd r2, [sp, #88] ldr r0, [sp, #44] str r2, [r3] add sp, sp, #124 @ sp needed pop {r4, r5, r6, r7, r8, r9, r10, fp, pc} .L175: ldrd r10, [sp, #180] mov r2, r3 str r0, [sp, #40] str r8, [sp, #44] .L103: ldr r3, [sp, #168] ldr r1, [sp, #112] ldr r3, [r3, r2, lsl #2] add r3, r3, r1 ldr r1, [sp, #168] str r3, [r1, r2, lsl #2] .L106: ldr r2, [sp, #20] ldr r1, [sp, #44] cmp r2, r1 bge .L113 .L177: mvn r3, r2 add r3, r3, r1 cmp r3, #6 ldr r3, [sp, #24] sub r5, r1, r2 ldr r8, [r3, #24] bls .L178 ldr r3, [sp, #168] lsr r4, r5, #3 ldr r2, [sp, #84] add r9, r3, r2 ldr r3, [sp, #52] add r4, r9, r4, lsl #5 add r7, r8, r3 add ip, r3, #2 ldr r3, [sp, #40] add ip, r8, ip mov r2, r9 mov lr, r7 vdup.32 q13, r3 mov r3, r9 .L115: add r0, r3, #16 mov r1, r2 vld1.16 {q8}, [ip]! add r2, r2, #32 cmp r4, r2 vld1.16 {q9}, [lr]! vmovl.s16 q12, d16 vmovl.s16 q8, d17 vmovl.s16 q14, d18 vld1.32 {q11}, [r3] vmovl.s16 q9, d19 add r3, r3, #32 vld1.32 {q10}, [r0] vsub.i32 q12, q12, q14 vsub.i32 q8, q8, q9 vmla.i32 q11, q12, q13 vmla.i32 q10, q8, q13 vst1.32 {q11}, [r1]! vst1.32 {q10}, [r1] bne .L115 bic r3, r5, #7 ldr r2, [sp, #20] cmp r3, r5 add r3, r2, r3 str r3, [sp, #20] beq .L116 .L114: ldr r4, [sp, #20] mov r3, r8 ldr r2, [sp, #44] add r1, r4, #1 ldr r0, [sp, #168] cmp r1, r2 ldr r5, [sp, #40] lsl ip, r1, #1 ldr lr, [r0, r4, lsl #2] ldrsh r2, [r3, ip]! ldrsh r0, [r3, #-2] sub r2, r2, r0 ldr r0, [sp, #168] mla r2, r5, r2, lr str r2, [r0, r4, lsl #2] bge .L116 ldr lr, [sp, #44] add r0, r4, #2 ldrsh ip, [r8, ip] cmp r0, lr ldr lr, [sp, #168] ldrsh r2, [r3, #2] ldr lr, [lr, r1, lsl #2] sub r2, r2, ip ldr ip, [sp, #168] mla r2, r5, r2, lr str r2, [ip, r1, lsl #2] bge .L116 ldr lr, [sp, #44] add r1, r4, #3 ldrsh ip, [r3, #2] cmp lr, r1 ldr lr, [sp, #168] ldrsh r2, [r3, #4] ldr lr, [lr, r0, lsl #2] sub r2, r2, ip ldr ip, [sp, #168] mla r2, r5, r2, lr str r2, [ip, r0, lsl #2] ble .L116 ldr lr, [sp, #44] add r0, r4, #4 ldrsh ip, [r3, #4] cmp lr, r0 ldr lr, [sp, #168] ldrsh r2, [r3, #6] ldr lr, [lr, r1, lsl #2] sub r2, r2, ip ldr ip, [sp, #168] mla r2, r5, r2, lr str r2, [ip, r1, lsl #2] ble .L116 ldr lr, [sp, #44] add r1, r4, #5 ldrsh ip, [r3, #6] cmp lr, r1 ldr lr, [sp, #168] ldrsh r2, [r3, #8] ldr lr, [lr, r0, lsl #2] sub r2, r2, ip ldr ip, [sp, #168] mla r2, r5, r2, lr str r2, [ip, r0, lsl #2] ble .L116 ldr lr, [sp, #44] add r0, r4, #6 ldrsh ip, [r3, #8] cmp lr, r0 ldr lr, [sp, #168] ldrsh r2, [r3, #10] ldr lr, [lr, r1, lsl #2] sub r2, r2, ip ldr ip, [sp, #168] mla r2, r5, r2, lr str r2, [ip, r1, lsl #2] ble .L116 ldrsh r2, [r3, #12] ldrsh r3, [r3, #10] ldr r1, [ip, r0, lsl #2] sub r3, r2, r3 mla r3, r5, r3, r1 str r3, [ip, r0, lsl #2] .L116: ldr r3, [sp, #44] mov r4, r9 mov r1, r9 mov r2, r7 add ip, r8, r3, lsl #1 .L117: mov r0, r2 add r2, r2, #2 ldrsh r3, [r0, #2] ldrsh lr, [r0] ldr r0, [r1] sub r3, r3, lr cmp r3, r6 movge r3, r6 cmp ip, r2 sub r6, r6, r3 add r3, r3, r0 str r3, [r1], #4 bne .L117 lsl r9, fp, #3 ldr r5, [sp, #116] mov r6, #0 mov r2, r9 ldr r9, [sp, #172] .L128: mov r3, r7 ldrsh r1, [r7, #2] ldrsh r3, [r3] add r7, r7, #2 lsl ip, r5, #1 sub r1, r1, r3 lsl r1, r1, fp cmp r1, #1 ble .L118 ldr r3, [sp, #24] cmp r1, #2 mul r0, r1, r10 ldr lr, [r3, #80] sub r3, r10, #2 clz r3, r3 ldrsh r1, [lr, ip] mvn ip, #20 mul r8, ip, r0 add r1, r1, r2 lsr r3, r3, #5 movle r3, #0 mul r1, r0, r1 andgt r3, r3, #1 add r3, r3, r0 lsleq r0, r0, #3 ldr ip, [r4] lsl lr, r3, #1 add r8, r8, r1, asr #1 addeq r8, r8, r0, asr #2 add r0, ip, r8 cmp r0, r3, lsl #4 bge .L120 add r8, r8, r1, asr #2 add r0, ip, r8 .L121: lsl r1, r3, #3 add r0, r0, r3, lsl #2 str r2, [sp, #4] str r1, [sp] bl __aeabi_idiv ldr r1, [sp] ldr r2, [sp, #4] bic r0, r0, r0, asr #31 str r0, [r9, r5, lsl #2] ldr r3, [r4] mul r1, r0, r1 add r8, r8, r3 ldr r3, [sp, #176] cmp r1, r8 movlt r1, #0 movge r1, #1 str r1, [r3, r5, lsl #2] ldr r3, [r9, r5, lsl #2] ldr r1, [r4] mul r0, r3, r10 cmp r0, r1, asr #3 ldr r0, [sp, #44] ldrgt r3, [sp, #60] asrgt r3, r1, r3 asrgt r3, r3, #3 strgt r3, [r9, r5, lsl #2] cmp r3, #7 movgt r3, #7 strgt r3, [r9, r5, lsl #2] mul r3, r3, r10 add r5, r5, #1 ldr r1, [r4] cmp r0, r5 sub r3, r1, r3, lsl #3 str r3, [r4], #4 bgt .L128 str r0, [sp, #20] b .L113 .L118: ldr r3, [r4] ldr r1, [sp, #60] asr r3, r3, r1 cmp r3, #63 asr r3, r3, #3 movgt r1, #7 movgt r3, #8 bgt .L125 cmp r3, #1 movlt r3, #1 sub r1, r3, #1 .L125: mul r3, r3, r10 str r1, [r9, r5, lsl #2] ldr r0, [r4] add r1, r5, #1 sub r6, r0, r6 ldr r0, [sp, #176] cmp r6, r3, lsl #3 movle r3, #1 movgt r3, #0 str r3, [r0, r5, lsl #2] ldr r0, [r9, r5, lsl #2] ldr r3, [sp, #44] mla r6, r0, r10, r10 cmp r3, r1 ldr r3, [r4] sub r6, r3, r6, lsl #3 bic r6, r6, r6, asr #31 bgt .L179 mul r2, r0, r10 ldr r1, [sp, #44] str r1, [sp, #20] sub r3, r3, r2, lsl #3 str r3, [r4] b .L113 .L120: add lr, lr, r3 cmp r0, lr, lsl #3 addlt r8, r8, r1, asr #3 addlt r0, ip, r8 b .L121 .L179: ldr r0, [r4, #4] sub r3, r3, r6 str r3, [r4] add r0, r0, r6 str r0, [r4, #4] ldr r0, [r9, r5, lsl #2] mov r5, r1 mul r1, r0, r10 sub r3, r3, r1, lsl #3 str r3, [r4], #4 b .L128 .L174: mov fp, r3 ldr r3, [sp, #32] str r2, [sp, #40] mov r2, #1 ldr r0, [sp, #188] mov r1, r2 ldr r10, [sp, #180] str r3, [sp, #44] bl ec_enc_bit_logp b .L106 .L178: ldr r3, [sp, #168] ldr r2, [sp, #84] add r9, r3, r2 ldr r3, [sp, #52] add r7, r8, r3 b .L114 .L130: ldr r0, [sp, #168] ldr lr, [sp, #72] ldr r4, [sp, #60] add lr, r0, lr .L135: ldr r0, [r2] asr r0, r0, r4 asr r0, r0, #3 str r0, [ip] str r1, [r2], #4 ldr r0, [ip], #4 cmp r0, #0 movgt r0, #0 movle r0, #1 cmp r2, lr str r0, [r3], #4 bne .L135 b .L133 .L74: ldr r3, [sp, #24] ldr r1, [sp, #16] ldr r3, [r3, #24] str r3, [sp, #80] lsl r3, r10, #3 str r3, [sp, #8] ldr r3, [sp, #20] lsl r3, r3, #2 str r3, [sp, #84] b .L77 .L140: str ip, [sp, #28] b .L87 .L144: ldr r0, [sp, #12] ldr r5, [sp, #36] b .L100 .L173: ldr r3, [sp, #16] str r2, [sp, #28] ldr r2, [sp, #28] str r3, [sp, #44] b .L103 .size compute_allocation, .-compute_allocation .section .rodata.maxK.8118,"a" .align 3 .set .LANCHOR0,. + 0 .type maxK.8118, %object .size maxK.8118, 30 maxK.8118: .short 32767 .short 32767 .short 32767 .short 32767 .short 1172 .short 238 .short 95 .short 53 .short 36 .short 27 .short 22 .short 18 .short 16 .short 15 .short 13 .section .rodata.maxN.8117,"a" .align 3 .set .LANCHOR1,. + 0 .type maxN.8117, %object .size maxN.8117, 30 maxN.8117: .short 32767 .short 32767 .short 32767 .short 1476 .short 283 .short 109 .short 60 .short 40 .short 29 .short 24 .short 20 .short 18 .short 16 .short 14 .short 13 .ident "GCC: (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]" А вот нерабочий вариант, приводящий CPU в исключение Abort: Spoiler .section .text.compute_allocation,"ax",%progbits .align 2 .global compute_allocation .syntax unified .arm .fpu neon .type compute_allocation, %function compute_allocation: @ args = 40, pretend = 0, frame = 128 @ frame_needed = 0, uses_anonymous_args = 0 push {r4, r5, r6, r7, r8, r9, r10, fp, lr} movw lr, #:lower16:global_stack vpush.64 {d8, d9, d10, d11, d12, d13, d14, d15} movt lr, #:upper16:global_stack mov r8, r1 mov r7, lr sub sp, sp, #132 str r2, [sp, #40] ldr r2, [r0, #8] ldr ip, [sp, #236] str r3, [sp, #112] cmp ip, #7 str r2, [sp, #64] ldr r2, [lr] bic r3, ip, ip, asr #31 ldr r6, [sp, #64] str r3, [sp, #24] subgt r3, r3, #8 movle r3, #0 strgt r3, [sp, #24] movgt r3, #8 str r3, [sp, #120] rsb r3, r2, #0 strd r0, [sp, #32] and r3, r3, #3 lsl r0, r6, #2 mov r4, r2 str r2, [sp, #100] add r2, r2, r3 str r2, [sp, #96] add r2, r2, r0 str lr, [sp, #104] rsb lr, r2, #0 ldr r10, [sp, #40] and lr, lr, #3 ldr fp, [sp, #252] add r2, r2, lr str r2, [sp, #108] add r2, r2, r0 cmp r1, r10 rsb ip, r2, #0 and ip, ip, #3 add r9, r2, ip add r1, r9, r0 rsb r2, r1, #0 and r2, r2, #3 add r1, r1, r2 str r1, [sp, #84] add r1, r1, r0 str r1, [r7] bge .L74 add r3, r3, r6, lsl #3 add r7, r8, #8 add r0, r0, r3 add r3, lr, r3 add r3, r3, ip lsl r7, r7, #2 add r1, r4, r3 add r0, r0, lr ldr r3, [sp, #32] mov lr, r4 add r0, r0, ip sub r4, r7, #32 add ip, r3, #12 add r0, r0, r2 add r2, r1, r4 add r0, lr, r0 cmp ip, r2 lsl r5, r10, #2 add r6, r0, r7 add r3, r0, r4 str r5, [sp, #88] add r5, r1, r5 add r1, r1, r7 ldr r7, [sp, #32] movhi lr, #0 movls lr, #1 cmp r2, r6 cmpcc r3, r1 sub r6, r10, #1 add r7, r7, #8 str r6, [sp, #72] movcs r1, #1 movcc r1, #0 cmp r7, r5 orrcs lr, lr, #1 mov r5, r6 mov r6, r8 sub r5, r5, r8 ldr r8, [sp, #88] cmp ip, r3 add r0, r0, r8 movhi ip, #0 movls ip, #1 cmp r5, #6 movls lr, #0 andhi lr, lr, #1 cmp r7, r0 movcc r0, ip orrcs r0, ip, #1 ldr r7, [sp, #32] and r1, r1, lr ldr lr, [sp, #256] tst r1, r0 ldr r0, [sp, #232] ldr ip, [r7, #24] add r7, lr, #3 sub r1, r0, #5 ldr r0, [sp, #256] str ip, [sp, #92] sub r8, r1, r0 lsl r0, fp, #3 str r0, [sp, #20] beq .L75 add r1, r6, #1 mov lr, ip sub r10, r10, r6 vdup.32 q3, r6 lsl r1, r1, #1 vmov.i32 q6, #3 @ v4si add ip, ip, r1 sub r1, r1, #2 add r5, lr, r1 ldr r1, [sp, #64] lsr r0, r10, #3 vldr d16, .L219 vldr d17, .L219+8 vmov.i32 q5, #4294967295 @ v4si mov r4, r3 vdup.32 q2, r1 ldr r1, [sp, #256] add r6, ip, r0, lsl #4 lsl r0, fp, #3 vmov.i32 q4, #1 @ v4si vdup.32 q0, fp vadd.i32 q3, q3, q8 mov lr, r3 vdup.32 q8, r7 vdup.32 q14, r0 vdup.32 q1, r8 vdup.32 q13, r1 vst1.64 {d16-d17}, [sp:64] b .L220 .L221: .align 3 .L219: .word 0 .word 1 .word 2 .word 3 .L220: .L76: vmov.i32 q8, #8 @ v4si mov r0, r2 vld1.16 {q10}, [ip]! vmov q9, q3 @ v4si add r1, r3, #16 add r2, r2, #32 vadd.i32 q3, q3, q8 vld1.16 {q8}, [r5]! vmovl.s16 q12, d20 cmp ip, r6 vmovl.s16 q10, d21 vmovl.s16 q11, d16 vmovl.s16 q8, d17 vsub.i32 q7, q2, q9 vsub.i32 q11, q12, q11 vsub.i32 q8, q10, q8 vmov.i32 q10, #4 @ v4si vadd.i32 q7, q7, q5 vmul.i32 q15, q8, q0 vadd.i32 q9, q9, q10 vmul.i32 q10, q11, q0 vmul.i32 q12, q11, q6 vmul.i32 q15, q15, q1 vmul.i32 q10, q10, q1 vsub.i32 q9, q2, q9 vshl.s32 q12, q12, q13 vadd.i32 q9, q9, q5 vshl.s32 q11, q11, q13 vmul.i32 q10, q10, q7 vmul.i32 q7, q8, q6 vmul.i32 q9, q9, q15 vld1.64 {d30-d31}, [sp:64] vshl.i32 q12, q12, #3 vshl.s32 q7, q7, q13 vshl.s32 q10, q10, q15 vshl.i32 q7, q7, #3 vshr.s32 q12, q12, #4 vshl.s32 q9, q9, q15 vshr.s32 q7, q7, #4 vmax.s32 q12, q12, q14 vshr.s32 q10, q10, #6 vmax.s32 q7, q7, q14 vshl.s32 q8, q8, q13 vst1.32 {q12}, [r0]! vceq.i32 q11, q11, q4 vshr.s32 q9, q9, #6 vst1.32 {q7}, [r0] vsub.i32 q12, q10, q14 mov r0, lr vld1.32 {q15}, [r3] vceq.i32 q8, q8, q4 vbit q10, q12, q11 add lr, lr, #32 vld1.32 {q7}, [r1] mov r1, r4 vbsl q11, q12, q15 add r3, r3, #32 add r4, r4, #32 vsub.i32 q12, q9, q14 vbit q7, q12, q8 vst1.32 {q11}, [r0]! vbit q9, q12, q8 vst1.32 {q7}, [r0] vst1.32 {q10}, [r1]! vst1.32 {q9}, [r1] bne .L76 bic r0, r10, #7 ldr r3, [sp, #36] cmp r10, r0 add r4, r0, r3 beq .L207 add r0, r4, #1 ldr lr, [sp, #92] ldr r5, [sp, #256] lsl ip, r0, #1 ldrsh r2, [lr, ip]! ldrsh r3, [lr, #-2] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, r5 lsl r2, r2, r5 ldr r5, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, r5 movlt r1, r5 cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r4, lsl #2] ldr r2, [r2, #8] sub r2, r2, r4 sub r2, r2, #1 mul r3, r3, r2 moveq r2, r5 lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r4, lsl #2] ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldr r3, [sp, #92] ldrsh r2, [lr, #2] ldrsh r3, [r3, ip] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] add r0, r4, #2 ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldrsh r3, [lr, #2] ldrsh r2, [lr, #4] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] add r0, r4, #3 ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldrsh r3, [lr, #4] ldrsh r2, [lr, #6] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] add r0, r4, #4 ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldrsh r3, [lr, #6] ldrsh r2, [lr, #8] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] add r0, r4, #5 ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldrsh r3, [lr, #8] ldrsh r2, [lr, #10] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] add r0, r4, #6 ldr r3, [sp, #40] cmp r3, r0 ble .L206 ldrsh r3, [lr, #10] ldrsh r2, [lr, #12] ldr ip, [sp, #256] sub r2, r2, r3 add r1, r2, r2, lsl #1 mul r3, r2, fp lsl r1, r1, ip lsl r2, r2, ip ldr ip, [sp, #20] sbfx r1, r1, #1, #28 cmp r1, ip movlt r1, ip cmp r2, #1 ldr r2, [sp, #32] mul r3, r8, r3 str r1, [r9, r0, lsl #2] ldr r2, [r2, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 moveq r2, ip lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, r2 ldr r2, [sp, #84] str r3, [r2, r0, lsl #2] ldr r3, [sp, #36] lsl r3, r3, #1 str r3, [sp, #68] b .L78 .L74: ldr r3, [sp, #32] ldr r3, [r3, #24] str r3, [sp, #92] lsl r3, fp, #3 str r3, [sp, #20] ldr r3, [sp, #40] lsl r2, r3, #2 sub r3, r3, #1 str r2, [sp, #88] str r3, [sp, #72] .L206: ldr r3, [sp, #36] .L207: lsl r3, r3, #1 str r3, [sp, #68] .L78: ldr r3, [sp, #32] lsl r1, fp, #9 ldr r2, [sp, #88] ldr ip, [sp, #40] ldr r3, [r3, #28] add r0, r9, r2 str r0, [sp] sub r3, r3, #2 str r3, [sp, #44] ldr r3, [sp, #256] ldr r0, [sp, #92] lsl r10, r1, r3 ldr r3, [sp, #96] add ip, r0, ip, lsl #1 str r1, [sp, #116] add r3, r3, r2 str r3, [sp, #60] ldr r3, [sp, #112] str ip, [sp, #52] add r3, r3, r2 str r3, [sp, #76] ldr r3, [sp, #84] add r3, r3, r2 str r3, [sp, #80] ldr r3, [sp, #68] add r9, r0, r3 ldr r3, [sp, #72] str r3, [sp, #56] ldr r3, [sp, #36] str r3, [sp, #124] mov r3, #1 str r3, [sp, #28] .L106: ldr r3, [sp, #36] ldr r2, [sp, #40] cmp r3, r2 ldr r3, [sp, #28] ldr r2, [sp, #44] add r3, r3, r2 asr r3, r3, #1 str r3, [sp, #48] bge .L158 ldr r1, [sp, #72] mov r7, #0 ldr r2, [sp, #64] mov r4, r7 ldr lr, [sp, #80] ldr r6, [sp] mla ip, r3, r2, r1 ldr r3, [sp, #32] ldr r5, [sp, #76] ldr r0, [sp, #60] ldr r3, [r3, #32] add ip, ip, #1 ldr r1, [sp, #52] add ip, r3, ip b .L102 .L209: cmp r3, r10 addle r7, r7, r3 addgt r7, r7, r10 cmp r1, r9 sub lr, lr, #4 beq .L98 .L102: ldrsh r2, [r1] ldrsh r8, [r1, #-2]! ldrb r3, [ip, #-1]! @ zero_extendqisi2 sub r2, r2, r8 mul r2, fp, r2 mul r3, r3, r2 ldr r2, [sp, #256] lsl r3, r3, r2 asr r3, r3, #2 str r3, [r0, #-4]! cmp r3, #0 ldrgt r2, [lr, #-4] addgt r3, r3, r2 bicgt r3, r3, r3, asr #31 strgt r3, [r0] ldr r2, [r5, #-4]! add r3, r3, r2 str r3, [r0] ldr r2, [r6, #-4]! cmp r3, r2 movlt r2, r4 orrge r2, r4, #1 mov r4, #1 cmp r2, #0 bne .L209 ldr r8, [sp, #20] sub lr, lr, #4 mov r4, r2 cmp r3, r8 addge r7, r7, r8 cmp r1, r9 bne .L102 .L98: ldr r3, [sp, #24] cmp r7, r3 ldr r3, [sp, #48] ble .L103 ldr r2, [sp, #28] sub r3, r3, #1 str r3, [sp, #44] cmp r2, r3 ble .L106 .L105: ldr r3, [sp, #40] ldr r1, [sp, #36] cmp r1, r3 ldr r3, [sp, #28] sub r7, r3, #1 bge .L160 ldr ip, [sp, #64] lsl r6, r1, #2 ldr r2, [sp, #32] ldr r0, [sp, #112] mul r3, r7, ip ldr r2, [r2, #32] add r4, r0, r6 str r7, [sp, #28] ldr r0, [sp, #96] add lr, r3, ip add r3, r3, r1 add lr, lr, r1 add r5, r2, r3 ldr r8, [sp, #84] mov ip, r1 ldr r3, [sp, #108] add lr, r2, lr ldr r7, [sp, #256] add r0, r0, r6 add r1, r3, r6 str r6, [sp, #80] mov r6, ip str r10, [sp, #44] .L113: mov r2, r9 ldrsh r3, [r9, #2] ldrsh r10, [r2] add r9, r9, #2 ldrb r2, [r5], #1 @ zero_extendqisi2 sub r3, r3, r10 mul r3, fp, r3 mul r2, r3, r2 lsl r2, r2, r7 asr r2, r2, #2 str r2, [r0] ldrb r2, [lr], #1 @ zero_extendqisi2 mul r3, r3, r2 lsl r3, r3, r7 asr r3, r3, #2 str r3, [r1], #4 ldr r2, [r0], #4 cmp r2, #0 ldrgt r3, [r8, ip, lsl #2] addgt r3, r3, r2 bicgt r3, r3, r3, asr #31 strgt r3, [r0, #-4] ldrgt r3, [r1, #-4] cmp r3, #0 ldrgt r2, [r8, ip, lsl #2] addgt r3, r3, r2 ldr r2, [sp, #28] bicgt r3, r3, r3, asr #31 strgt r3, [r1, #-4] cmp r2, #0 ldrgt r3, [r0, #-4] ldrgt r2, [r4] addgt r3, r3, r2 strgt r3, [r0, #-4] ldr r2, [r4] ldrgt r3, [r1, #-4] add r3, r3, r2 str r3, [r1, #-4] ldr r10, [r4], #4 ldr r2, [r0, #-4] cmp r10, #0 ldr r10, [sp, #52] sub r3, r3, r2 str r3, [r1, #-4] movgt r6, ip cmp r9, r10 add ip, ip, #1 bne .L113 ldr r10, [sp, #44] str r6, [sp, #44] .L107: ldr r3, [sp, #108] cmp fp, #1 ldr r2, [sp, #88] mov r8, #0 str fp, [sp, #252] add r9, r3, r2 ldr r3, [sp, #96] ldr r2, [sp, #80] str r9, [sp, #28] ldr r9, [sp, #20] add r7, r3, r2 movle r3, #0 movgt r3, #1 str r3, [sp, #76] mov r3, #6 str r3, [sp, #64] mov r3, #64 mov fp, r3 .L119: ldr r3, [sp, #36] add r6, r8, fp ldr r2, [sp, #40] mov r4, #0 asr r6, r6, #1 cmp r3, r2 bge .L114 ldr lr, [sp] mov r0, r4 ldr ip, [sp, #28] ldr r1, [sp, #60] b .L117 .L210: cmp r10, r3 addle r4, r4, r10 addgt r4, r4, r3 cmp r1, r7 beq .L114 .L117: ldr r5, [ip, #-4]! ldr r3, [r1, #-4]! ldr r2, [lr, #-4]! mul r5, r5, r6 add r3, r3, r5, asr #6 cmp r2, r3 movgt r2, r0 orrle r2, r0, #1 mov r0, #1 cmp r2, #0 bne .L210 cmp r9, r3 mov r0, r2 addle r4, r4, r9 cmp r1, r7 bne .L117 .L114: ldr r3, [sp, #24] cmp r4, r3 ldr r3, [sp, #64] movgt fp, r6 movle r8, r6 subs r3, r3, #1 str r3, [sp, #64] bne .L119 ldr r3, [sp, #36] ldr r2, [sp, #40] ldr r9, [sp, #28] cmp r3, r2 ldr fp, [sp, #252] bge .L164 ldr r3, [sp, #116] ldr r2, [sp, #256] ldr r0, [sp, #64] lsl ip, r3, r2 ldr r3, [sp, #240] ldr r2, [sp, #88] ldr lr, [sp] mov r5, r0 ldr r1, [sp, #60] add r4, r3, r2 b .L122 .L121: cmp ip, r3 movlt r3, ip cmp r1, r7 add r5, r5, r3 str r3, [r4, #-4]! beq .L211 .L122: ldr r3, [r9, #-4]! eor r2, r0, #1 ldr r10, [r1, #-4]! mov r0, #1 ldr r6, [lr, #-4]! mul r3, r3, r8 add r3, r10, r3, asr #6 cmp r6, r3 movle r2, #0 andgt r2, r2, #1 cmp r2, #0 beq .L121 ldr r2, [sp, #20] mov r0, #0 cmp r2, r3 mov r3, r0 movle r3, r2 b .L121 .L103: ldr r2, [sp, #44] add r3, r3, #1 str r3, [sp, #28] cmp r2, r3 bge .L106 b .L105 .L158: mov r7, #0 b .L98 .L211: ldr r3, [sp, #24] sub r0, r3, r5 .L120: ldr r3, [sp, #52] ldr r2, [sp, #68] ldrsh r4, [r3] ldr r3, [sp, #92] ldrsh r10, [r3, r2] sub r1, r4, r10 bl __aeabi_idivmod ldr r3, [sp, #44] ldr r2, [sp, #72] cmp r3, r2 mov r7, r0 mov r6, r1 bge .L212 ldr r3, [sp, #20] ldr r2, [sp, #88] add r3, r3, #8 str r3, [sp, #48] ldr r3, [sp, #240] ldr r9, [sp, #56] add r8, r3, r2 str fp, [sp, #252] mov r3, r10 ldr r10, [sp, #92] b .L125 .L215: ldr r3, [sp, #268] cmp r3, r9 movgt r3, #7 movle r3, #9 mul lr, r3, lr ldr r3, [sp, #256] lsl lr, lr, r3 sbfx lr, lr, #1, #28 cmp r4, lr bgt .L213 ldr r0, [sp, #260] mov r2, #1 mov r1, #0 bl ec_enc_bit_logp .L131: ldr r3, [sp, #32] add r5, r5, #8 ldr ip, [r8] sub r4, r4, #8 ldr r10, [r3, #24] ldr r3, [sp, #68] ldrsh r3, [r10, r3] .L127: ldr r2, [sp, #20] sub r5, r5, ip cmp r4, r2 addge r5, r5, r2 movlt r2, #0 .L132: ldrsh r4, [r10, fp] sub fp, r9, #1 ldr r1, [sp, #24] str r2, [r8] sub r0, r1, r5 sub r1, r4, r3 str r3, [sp, #28] bl __aeabi_idivmod ldr r3, [sp, #44] cmp fp, r3 ldr r3, [sp, #28] mov r7, r0 mov r6, r1 beq .L214 mov r9, fp .L125: lsl fp, r9, #1 ldr ip, [r8, #-4]! ldr r2, [sp] ldrsh r1, [r10, fp] sub lr, r4, r1 sub r1, r1, r3 sub r1, r6, r1 ldr r0, [r2, #-4]! mla r4, r7, lr, ip str r2, [sp] add r2, r9, #1 cmp r1, #0 addge r4, r4, r1 ldr r1, [sp, #48] cmp r1, r0 movge r0, r1 cmp r4, r0 blt .L127 ldr r3, [sp, #264] cmp r3, #0 bne .L215 ldr r0, [sp, #260] mov r1, #1 str r2, [sp, #28] bl ec_dec_bit_logp ldr r2, [sp, #28] cmp r0, #0 beq .L131 str r2, [sp, #56] ldr r1, [sp, #56] ldr r2, [sp, #36] ldr fp, [sp, #252] cmp r2, r1 blt .L216 .L133: ldrd r2, [sp, #36] cmp r3, r2 ble .L153 ldr r3, [sp, #72] add r1, r2, #4 mov r6, r2 ldr r0, [sp, #248] sub r5, r3, r2 ldr r2, [sp, #240] lsl r1, r1, #2 add lr, r2, r1 ldr r2, [sp, #244] sub r3, r1, #16 add ip, r2, r3 ldr r2, [sp, #240] add r2, r2, r3 add r3, r0, r3 ldr r0, [sp, #244] add r4, r0, r1 ldr r0, [sp, #248] cmp r2, r4 cmpcc ip, lr add r1, r0, r1 movcs r0, #1 movcc r0, #0 cmp r2, r1 cmpcc r3, lr movcs lr, #1 movcc lr, #0 cmp r3, r4 cmpcc ip, r1 and lr, lr, r0 movcs r1, #1 movcc r1, #0 cmp r5, #3 movls lr, #0 andhi lr, lr, #1 ands r1, lr, r1 beq .L150 ldr r1, [sp, #40] vmov.i32 q9, #0 @ v4si vmov.i32 q11, #1 @ v4si sub r5, r1, r6 ldr r1, [sp, #76] lsr r4, r5, #2 vdup.32 q10, r1 ldr r1, [sp, #64] lsl r4, r4, #4 vneg.s32 q10, q10 .L151: add lr, r2, r1 add r0, ip, r1 add r6, r3, r1 add r1, r1, #16 vld1.32 {q8}, [lr] cmp r1, r4 vshl.s32 q8, q8, q10 vshr.s32 q8, q8, #3 vst1.32 {q8}, [r0] vst1.32 {q9}, [lr] vld1.32 {q8}, [r0] vcle.s32 q8, q8, #0 vbsl q8, q11, q9 vst1.32 {q8}, [r6] bne .L151 bic r3, r5, #3 ldr r2, [sp, #36] cmp r3, r5 add r3, r3, r2 beq .L153 ldr r2, [sp, #240] mov r0, #0 ldr lr, [sp, #76] add ip, r3, #1 ldr r4, [sp, #244] ldr r1, [r2, r3, lsl #2] lsl r2, r3, #2 asr r1, r1, lr asr r1, r1, #3 str r1, [r4, r3, lsl #2] ldr r1, [sp, #240] str r0, [r1, r3, lsl #2] ldr r1, [r4, r3, lsl #2] ldr r4, [sp, #40] cmp r1, r0 movgt r1, #0 movle r1, #1 cmp ip, r4 ldr ip, [sp, #248] str r1, [ip, r3, lsl #2] bge .L153 ldr ip, [sp, #240] add r1, r2, #4 ldr r5, [sp, #244] add r3, r3, #2 ldr ip, [ip, r1] asr ip, ip, lr asr ip, ip, #3 str ip, [r5, r1] ldr ip, [sp, #240] str r0, [ip, r1] ldr ip, [r5, r1] cmp ip, r0 movgt ip, #0 movle ip, #1 cmp r4, r3 ldr r3, [sp, #248] str ip, [r3, r1] ble .L153 add r3, r2, #8 ldr r2, [sp, #240] ldr r1, [sp, #248] ldr r2, [r2, r3] asr r2, r2, lr asr r2, r2, #3 str r2, [r5, r3] ldr r2, [sp, #240] str r0, [r2, r3] ldr r2, [r5, r3] cmp r2, r0 movgt r2, #0 movle r2, #1 str r2, [r1, r3] .L153: ldrd r2, [sp, #100] ldr r0, [sp, #56] str r2, [r3] add sp, sp, #132 @ sp needed vldm sp!, {d8-d15} pop {r4, r5, r6, r7, r8, r9, r10, fp, pc} .L214: ldr fp, [sp, #252] str r9, [sp, #56] .L123: ldr r2, [sp, #44] ldr r3, [sp, #240] ldr r1, [sp, #120] ldr r3, [r3, r2, lsl #2] add r3, r3, r1 ldr r1, [sp, #240] str r3, [r1, r2, lsl #2] .L126: ldr r2, [sp, #36] ldr r1, [sp, #56] cmp r2, r1 bge .L133 .L216: mvn r3, r2 add r3, r3, r1 cmp r3, #6 ldr r3, [sp, #32] sub r5, r1, r2 ldr r8, [r3, #24] bls .L217 ldr r3, [sp, #240] lsr r4, r5, #3 ldr r2, [sp, #80] vdup.32 q13, r7 add r9, r3, r2 ldr r3, [sp, #68] add r4, r9, r4, lsl #5 add r10, r8, r3 add ip, r3, #2 add ip, r8, ip mov r2, r9 mov r3, r9 mov lr, r10 .L135: vld1.16 {q8}, [ip]! add r0, r3, #16 mov r1, r2 add r2, r2, #32 vld1.16 {q9}, [lr]! vmovl.s16 q12, d16 vmovl.s16 q8, d17 cmp r2, r4 vmovl.s16 q14, d18 vld1.32 {q11}, [r3] vmovl.s16 q9, d19 add r3, r3, #32 vld1.32 {q10}, [r0] vsub.i32 q12, q12, q14 vsub.i32 q8, q8, q9 vmla.i32 q11, q12, q13 vmla.i32 q10, q8, q13 vst1.32 {q11}, [r1]! vst1.32 {q10}, [r1] bne .L135 bic r3, r5, #7 ldr r2, [sp, #36] cmp r3, r5 add r3, r2, r3 str r3, [sp, #36] beq .L136 .L134: ldr r4, [sp, #36] mov r3, r8 ldr r2, [sp, #240] add r1, r4, #1 ldr r5, [sp, #56] lsl ip, r1, #1 ldr lr, [r2, r4, lsl #2] cmp r1, r5 ldrsh r2, [r3, ip]! ldrsh r0, [r3, #-2] sub r2, r2, r0 ldr r0, [sp, #240] mla r2, r7, r2, lr str r2, [r0, r4, lsl #2] bge .L136 ldrsh ip, [r8, ip] mov lr, r0 ldrsh r2, [r3, #2] add r0, r4, #2 ldr lr, [lr, r1, lsl #2] cmp r5, r0 sub r2, r2, ip ldr ip, [sp, #240] mla r2, r7, r2, lr str r2, [ip, r1, lsl #2] ble .L136 ldrsh r2, [r3, #4] mov lr, ip ldrsh ip, [r3, #2] add r1, r4, #3 ldr lr, [lr, r0, lsl #2] cmp r5, r1 sub r2, r2, ip ldr ip, [sp, #240] mla r2, r7, r2, lr str r2, [ip, r0, lsl #2] ble .L136 ldrsh r2, [r3, #6] mov lr, ip ldrsh ip, [r3, #4] add r0, r4, #4 ldr lr, [lr, r1, lsl #2] cmp r5, r0 sub r2, r2, ip ldr ip, [sp, #240] mla r2, r7, r2, lr str r2, [ip, r1, lsl #2] ble .L136 ldrsh r2, [r3, #8] mov lr, ip ldrsh ip, [r3, #6] add r1, r4, #5 ldr lr, [lr, r0, lsl #2] cmp r1, r5 sub r2, r2, ip ldr ip, [sp, #240] mla r2, r7, r2, lr str r2, [ip, r0, lsl #2] bge .L136 ldrsh r2, [r3, #10] mov lr, ip ldrsh ip, [r3, #8] add r0, r4, #6 ldr lr, [lr, r1, lsl #2] cmp r0, r5 sub r2, r2, ip ldr ip, [sp, #240] mla r2, r7, r2, lr str r2, [ip, r1, lsl #2] bge .L136 ldrsh r2, [r3, #12] ldrsh r3, [r3, #10] ldr r1, [ip, r0, lsl #2] sub r3, r2, r3 mla r3, r7, r3, r1 str r3, [ip, r0, lsl #2] .L136: ldr r3, [sp, #56] mov r7, r10 mov r4, r9 mov r1, r9 mov r2, r10 add ip, r8, r3, lsl #1 .L137: mov r0, r2 add r2, r2, #2 ldrsh r3, [r0, #2] ldrsh lr, [r0] ldr r0, [r1] sub r3, r3, lr cmp r3, r6 movge r3, r6 cmp r2, ip sub r6, r6, r3 add r3, r3, r0 str r3, [r1], #4 bne .L137 ldr r3, [sp, #256] mov r6, #0 ldr r5, [sp, #124] mvn r10, #20 lsl r9, r3, #3 mov r2, r9 ldr r9, [sp, #244] .L148: mov r3, r7 ldrsh r1, [r7, #2] ldrsh r3, [r3] add r7, r7, #2 lsl ip, r5, #1 sub r1, r1, r3 ldr r3, [sp, #256] lsl r1, r1, r3 cmp r1, #1 ble .L138 ldr r3, [sp, #32] cmp r1, #2 mul r0, r1, fp ldr lr, [r3, #80] sub r3, fp, #2 clz r3, r3 ldrsh r1, [lr, ip] lsr r3, r3, #5 mul r8, r10, r0 add r1, r1, r2 andgt r3, r3, #1 movle r3, #0 mul r1, r0, r1 add r3, r3, r0 lsleq r0, r0, #3 ldr ip, [r4] lsl lr, r3, #1 add r8, r8, r1, asr #1 addeq r8, r8, r0, asr #2 add r0, ip, r8 cmp r0, r3, lsl #4 bge .L140 add r8, r8, r1, asr #2 add r0, ip, r8 .L141: lsl r1, r3, #3 add r0, r0, r3, lsl #2 str r2, [sp, #20] str r1, [sp] bl __aeabi_idiv ldr r1, [sp] ldr r2, [sp, #20] bic r0, r0, r0, asr #31 str r0, [r9, r5, lsl #2] ldr r3, [r4] mul r1, r0, r1 add r8, r8, r3 ldr r3, [sp, #248] cmp r1, r8 movlt r1, #0 movge r1, #1 str r1, [r3, r5, lsl #2] ldr r3, [r9, r5, lsl #2] ldr r1, [r4] mul r0, r3, fp cmp r0, r1, asr #3 ldr r0, [sp, #56] ldrgt r3, [sp, #76] asrgt r3, r1, r3 asrgt r3, r3, #3 strgt r3, [r9, r5, lsl #2] cmp r3, #7 movgt r3, #7 strgt r3, [r9, r5, lsl #2] mul r3, r3, fp add r5, r5, #1 ldr r1, [r4] cmp r0, r5 sub r3, r1, r3, lsl #3 str r3, [r4], #4 bgt .L148 str r0, [sp, #36] b .L133 .L138: ldr r3, [r4] ldr r1, [sp, #76] asr r3, r3, r1 cmp r3, #63 asr r3, r3, #3 movgt r1, #7 movgt r3, #8 bgt .L145 cmp r3, #1 movlt r3, #1 sub r1, r3, #1 .L145: mul r3, r3, fp str r1, [r9, r5, lsl #2] ldr r1, [r4] add r0, r5, #1 sub r6, r1, r6 ldr r1, [sp, #248] cmp r6, r3, lsl #3 movle r3, #1 movgt r3, #0 str r3, [r1, r5, lsl #2] ldr r1, [r9, r5, lsl #2] ldr r3, [sp, #56] mla r6, r1, fp, fp cmp r3, r0 ldr r3, [r4] sub r6, r3, r6, lsl #3 bic r6, r6, r6, asr #31 bgt .L218 mul r2, r1, fp ldr r1, [sp, #56] str r1, [sp, #36] sub r3, r3, r2, lsl #3 str r3, [r4] b .L133 .L140: add lr, lr, r3 cmp r0, lr, lsl #3 addlt r8, r8, r1, asr #3 addlt r0, ip, r8 b .L141 .L218: ldr r1, [r4, #4] sub r3, r3, r6 str r3, [r4] add r1, r1, r6 str r1, [r4, #4] ldr r1, [r9, r5, lsl #2] mov r5, r0 mul r1, r1, fp sub r3, r3, r1, lsl #3 str r3, [r4], #4 b .L148 .L213: mov r3, r2 mov r2, #1 ldr r0, [sp, #260] mov r1, r2 ldr fp, [sp, #252] str r3, [sp, #56] bl ec_enc_bit_logp b .L126 .L217: ldr r3, [sp, #240] ldr r2, [sp, #80] add r9, r3, r2 ldr r3, [sp, #68] add r10, r8, r3 b .L134 .L75: ldr r0, [sp, #36] add r4, r9, r4 str r9, [sp] mov r5, lr ldr r10, [sp, #84] lsl lr, fp, #3 lsl r3, r0, #1 ldr r6, [sp, #32] ldr r9, [sp, #40] add ip, ip, r3 str r3, [sp, #68] .L97: mov r3, ip ldrsh r2, [ip, #2] ldrsh r3, [r3] add ip, ip, #2 sub r2, r2, r3 mul r3, fp, r2 add r1, r2, r2, lsl #1 lsl r2, r2, r5 lsl r1, r1, r5 sbfx r1, r1, #1, #28 cmp r1, lr mul r3, r8, r3 movlt r1, lr cmp r2, #1 str r1, [r4], #4 ldr r2, [r6, #8] sub r2, r2, r0 sub r2, r2, #1 mul r3, r3, r2 lsl r3, r3, r7 asr r3, r3, #6 subeq r3, r3, lr str r3, [r10, r0, lsl #2] add r0, r0, #1 cmp r9, r0 bne .L97 ldr r9, [sp] b .L78 .L150: ldr r0, [sp, #240] ldr lr, [sp, #88] ldr r4, [sp, #76] add lr, r0, lr .L155: ldr r0, [r2] asr r0, r0, r4 asr r0, r0, #3 str r0, [ip] str r1, [r2], #4 ldr r0, [ip], #4 cmp r0, #0 movgt r0, #0 movle r0, #1 cmp r2, lr str r0, [r3], #4 bne .L155 b .L153 .L160: lsl r2, r1, #2 str r1, [sp, #44] str r2, [sp, #80] b .L107 .L164: ldr r0, [sp, #24] ldr r5, [sp, #64] b .L120 .L212: ldr r3, [sp, #40] str r2, [sp, #44] str r3, [sp, #56] b .L123 .size compute_allocation, .-compute_allocation .section .rodata.maxK.8118,"a" .align 3 .set .LANCHOR0,. + 0 .type maxK.8118, %object .size maxK.8118, 30 maxK.8118: .short 32767 .short 32767 .short 32767 .short 32767 .short 1172 .short 238 .short 95 .short 53 .short 36 .short 27 .short 22 .short 18 .short 16 .short 15 .short 13 .section .rodata.maxN.8117,"a" .align 3 .set .LANCHOR1,. + 0 .type maxN.8117, %object .size maxN.8117, 30 maxN.8117: .short 32767 .short 32767 .short 32767 .short 1476 .short 283 .short 109 .short 60 .short 40 .short 29 .short 24 .short 20 .short 18 .short 16 .short 14 .short 13 .ident "GCC: (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]" Думаем, решаем, высказываем догадки........ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться