Jump to content

    
Sign in to follow this  
__inline__

Cortex-A и GCC. (A13 + arm-none-eabi). Вопрос.

Recommended Posts

Добрый день!

 

Запустил вывод картинки на дисплей и вывод звука через встроенный кодек МК 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;
}

 

 

Edited by __inline__

Share this post


Link to post
Share on other sites

Что, всё так глухо, раз никто не написал ничего ?

 

Причина была в крайне неудачной реализации системы прерываний в 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 явно всё тухло...  Или я их пока ещё не раскурил? :biggrin:

 

По DMA, тоже не всё гладко.  ДМА работает если память источника и приёмника не кешируема.  Если хоть какой-то регион будет кешируемым, то даже Flush Data Cache не спасает - ДМА просто не стартует.  А это - "ОЙ"!  Так как мне нужен кешируемый участок памяти, так как я его ещё читаю (нужно вычитывать отдельные пикселы для проверки), так что буферизация на запись - спасает только при записи.

 

В общем, вывод такой.  Если сравнивать A13 и C6745, то последний однозначно более дружественен к игровым приложениям.  Я уже молчу о том, что драйвера sunxi-linux кривые настолько, что китайцы не различают - взятие адреса и само значение переменной, что часто приводило к вылету на эксепшн Abort или Undef.

 

P.S. Скачал armclang, входящий в состав ARM Development Studio - у них 90-дневная проба со всеми возможностями из-за ковида, потестил его.  В случае С++ - программа не стартует вообще! Опять намудрили что-то... В GCC всё стартует.

 

А теперь цены:  A13 - за 450 р и C6745 за 2500 р.   У первого всё через одно место (включая поддержку софтов), в во втором всё по-человечески сделано.

 

Финита ля комедия :cray:

Share this post


Link to post
Share on other sites
1 час назад, __inline__ сказал:

А теперь цены:  A13 - за 450 р и C6745 за 2500 р.   У первого всё через одно место (включая поддержку софтов), в во втором всё по-человечески сделано.

Это вполне норм. Еррату на А13 видели? Нет, потому, что ее никто не сделал или нет в открытом доступе, на техасовский ДСП она есть наверняка, только вот печаль в том, что А13 тоже далеко не безупречен, особенно в тех режимах, которые вы используете, вот такое и выстреливает порой... К счастью сам использовал видимо все это дело в обычных режимах, где работает все, что мне надо...

 

На счет прерываний - в А13 стоит очень упрощенный контроллер, в более поздних аллвиннерах используют GIC, но это все тоже мне не нравится, т.к. векторный сепаратор нужно делать программный, в отличии от М серии...

Edited by mantech

Share this post


Link to post
Share on other sites
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);

 И там такого полно :biggrin:

 

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

Edited by __inline__

Share this post


Link to post
Share on other sites
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МГц) и все вроде успевает....  Может что-то еще у вас есть не оптимального?

Edited by mantech

Share this post


Link to post
Share on other sites
32 minutes ago, mantech said:

Может что-то еще у вас есть не оптимального?

 

На C6745 всё превосходно работает и на меньших частотах.

 

33 minutes ago, mantech said:

но просто представил разрешение 400x240, сравнил его со своей задачей ...

 

Я не договорил :don-t_mention:

Ещё вдовесок к вышесказанному:

 

1) физический движок Box2D на плавучке

2) декодирование Opus

3) распаковка ZLIB

4) логика игры

5) свой графический API (рисование спрайтов с полу-прозрачностью, поворотом, отражением, перестановкой компонент, ....)

 

Share this post


Link to post
Share on other sites

Удалось всё-же запустить декодирование в обработчике прерывания.

Подтверждать прерывание надо ПОСЛЕ декодирования, а не ДО-:

 

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.   Если цикл оставить пустой, то декодирование работает.

 

Что за издевательство? Сильно похоже на конфликт за общую память.  Память внешняя, в ней код, данные.  Работает ДМА  и отображение кадра видео.

Edited by __inline__

Share this post


Link to post
Share on other sites
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, из темы:

 

за что ему большое спасибо!  :wink2:

 

Хотя, можно было ограничиться вот этим (без реализации вложенного прерывания) на манер синтаксиса 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 стек свой отдельно. :biggrin:

 

А вот для чего нужны __DSB() и __ISB()?  Кто может рассказать? :)

Edited by __inline__

Share this post


Link to post
Share on other sites
1 hour ago, __inline__ said:

А вот для чего нужны __DSB() и __ISB()?  Кто может рассказать? :)

Это барьерные операции. Они гарантируют, что следующие  за ней операции не будут начаты, пока не завершатся эти операции.

Собственно, лучше будет, если вы скажете, какое именно из предложений здесь http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html вам не понятно, чтобы понимать, начинать объяснение от Адама и Евы, или всё-таки поближе к программированию.

Share this post


Link to post
Share on other sites
3 hours ago, one_eight_seven said:

Это барьерные операции. Они гарантируют, что следующие  за ней операции не будут начаты, пока не завершатся эти операции.

Собственно, лучше будет, если вы скажете, какое именно из предложений здесь http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html вам не понятно, чтобы понимать, начинать объяснение от Адама и Евы, или всё-таки поближе к программированию.

 

Ваше объяснение мне более симпатично, чем на сайте arm.com.  То о чём они пишут, приходится многокоратно перечитывать, чтобы понять смысл.  Ещё более тяжелее представить ситуацию, где это действительно необходимо.

Share this post


Link to post
Share on other sites
8 minutes ago, __inline__ said:

 

Ваше объяснение мне более симпатично, чем на сайте arm.com.  То о чём они пишут, приходится многокоратно перечитывать, чтобы понять смысл.  Ещё более тяжелее представить ситуацию, где это действительно необходимо.

Где необходимо?

Там, где нужна синхронизация при работе с данными/инструкциями.

Наприме ISB - гарантирует, что операции, которые следуют после этой инструкции не будут считаны из памяти, пока не выполнится ISB.
Пример - включаете NEON или другой сопроцессор, и с помощью ISB  гарантируете, что опкоды сопроцессора не будут считываться из памяти, пока сопроцессор не будет включён.

DMB - это для работы с данными. Нужно, чтобы все мастера увидели все все данные, прежде, чем новые данные будут записаны в память или считаны из неё. Например, при работе с MMU или инвалидацией кэша.

DSB - как DMB, только распространяется на все инструкции, а не только на семейство ST/LD

Share this post


Link to post
Share on other sites

Обнаружил глюк 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.

 

Знающие, разъясните, почему такое имеет место быть?   Порядок типкаста отличается или как?

Share this post


Link to post
Share on other sites
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]"

 

 

 

Думаем, решаем, высказываем догадки........

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this