Jump to content

    

__inline__

Участник
  • Content Count

    768
  • Joined

  • Last visited

Everything posted by __inline__


  1. Проблема из-за вот этого: .text:_c_int00* > 0xC0000000 Если убрать, то бинарник становится маленьким, но entry point плавает. И в map-файле почему-то куча со стеком на младших адресах, ниже идёт код, данные...... Как можно принудительно заставить линковщик засовывать секции .stack и .sysmem в самый конец? (по старшим адресам) Пока ничего кроме как указать стартовый адрес стека, вычислив его дефайнами не приходит в голову.
  2. Я взял тот файл для линковщика, который мне CCS для C6745 предложил - называется он C6745.cmd. Это его содержимое. Хотите сказать что он неверный? Моя отсебятина там только - загон функции c_int00 в начало SDRAM. Атрибуты это что ? Можете выделить жирным в ваших скриптах линковщика? NOINIT - оно? PS: Ещё можно убедиться по map-файлу, что нет каких-то ещё выходных секций в несмежных с EMIFBSDRAM областях памяти. Может какие-то регистры периферии при старте прописываются. Тогда дырка между ними и EMIFBSDRAM будет заполнена. а вот это уже интересно! Я тоже сам писал. И что? нафига мне AIS в самописанном загрузчике?
  3. Всё хорошо, до тех пор пока программу пишите Вы сами. Приключения начинаются, когда занимаешься портированием чужих программ. К примеру декодер H264 - вся работа построена на куче, ибо туча буферов постоянно выделяются-высвобождаются туда-сюда, поверьте если оно б ненужно было, то никто кучу и работу с ней не изобретал,....... Мой файл для линковщика - всё как обычно: Так я ж сам загрузчик пишу, кладу файл бинарника сразу в SDRAM. Для чего мне заморачиваться с AIS? Файл разрастается на 2 этапе: objcopy -I elf32-little -O binary app_elf.bin app.bin .text:_c_int00* > 0xC0000000 Этим мы принудительно заставляем точку входа в программу быть с адреса начала SDRAM. HINT: И попутно эта функция ещё сбивает режим округления, так что только в main() его выставлять
  4. Фины же нордическая (белая) раса, чёрной она быть не может ) BlackFin - если что "Чёрный Плавник"... У AD всё с рыбами связано - вон Tiger Shark'и тоже - акулы.... А вообще смотрю я на STM32 и понимаю, что то чему рукоплещут миллионы хомячков по всему миру, это уже "дела давно минувших дней"... - многомерные DMA, память-память, видео-ускорители, наличие плавающей точки... - всё это уже давно было со времен DSP.
  5. А не пофиг ли, если для хобби (насколько я понял из этой темы "про вечное")? sitara туда же Честно говоря, мне непонятна озабоченность техасцев индусской стилистикой - в техподдержке у них почти все индусы. Вот докатились, что имена процессорам тоже дают индусские. У меня при слове "sitara" вот такая картинка в голове сразу рисуется: Эдакий, гуру микроконтроллеров, освоивший ситары )))
  6. У меня была аналогичная проблема с I2S на McASP в C6745. Нужно было избавиться от 32-битных пересылок - просто оттюнинговал оффсет в EDMA3 на значение =2 вместо 4, в итоге DMA стал отправлять в порт McASP 16-битные данные. Затем я избавился от второго канала и превратил I2S в I1S (просто надо MONO было, а не Stereo) - задал только один тайм-слот. Теперь память на второй канал не расходуется и он молчит (что и требовалось). EDMA3 настроил так: первое измерение ACNT=2 или 4 (размер семпла в байтах), второе измерение BCNT=64 (максимальный размер Audio FIFO), и наконец третье измерение = число кусков Audio FIFO в семплах. Качает до 16 МБ памяти в звук разом! В прерывании по окончанию DMA пересылки перезагружаю дескрипторы EDMA (PaRAM). Всё! Такого замечательного DMA я ещё нигде не встречал! АRМ-ы со своими 64K-DMA давятся в сторонке! =) Да, пришлось потрахаться с мануалами, порой даже на другие процессоры этого семейства, читать e2e, форумы, пережевывать китайские исходники, и.т.п. За 4 дня разобрался
  7. Ещё есть Мне не для аудиофилии, одного канала хватит за глаза, начиная с 12 бит (использую 16). Если это Cortex-A* , то вменяемой она в принципе быть не может! ))) Уже проходили! Кто-бы Cortex-M7 сделал бы на пару гигагерц с 64-разрядной шинами данных-адреса? Я о том же! Есть ПК для этого. Молодежи этого не понять - одни пыхтоны с линуксами... Sport это ж SPI, нет? В C6745 SPI всего два. А McASP - тоже два. В McASP - туча каналов! Ниже подробно.
  8. Кстати, вот надумалось применение для PRUSS - обработка кнопок джойстика от SEGA MegaDrive (Genesis). Для 6-кнопочного варианта важно выдержать интервалы между посылками, иначе джойстику сорвёт крышу и часть кнопок будет считываться неправильно. В свое время на ARM9 и BlackFin делал обработчик прерывания по таймеру и опрашивал кнопки. Но... от задержек я не ушёл! А с PRUSS эта задача становится лёгкой и не мешает основному CPU работать и отвлекаться на задержки. Код для BF532,533 ниже: Использование джойстика: https://eax.me/arduino-sega-controller/ Так как он КМОП, то и от напряжения 3.3V он тоже работает (проверено не раз)
  9. C6745 + кварц 24 МГц (такая частота делает возможной загрузку с UART) + контроллер сброса (использую MAX6390) + два питания (3.3V и 1.3V) = минимум. Я добавил ещё SPI EEPROM для автономной загрузки и SDRAM на 32 МБ - для своих целей. У C6745 тоже есть внутренние ОЗУ: 32+32+256 кБ, которые можно пустить на кеш 1-го и 2-го уровней - всю или не всю. Заливать там UART Boot Host'ом (прога от TI) - его возможности очень большие: часть секций может лить во внутреннюю, часть - во внешнюю память. У БлекФинов такого вроде не было (либо я опять что-то пропустил ))) Для моих применений без SDRAM нельзя - много данных будет: видео-буфера MPEG, ROM-ы эмуляторов и многое другое. Поэтому в моем случае оптимальный вариант, когда внутренняя память полностью расходуется на L1, L2 кеши. Заливаю через UART на 115200, да, медленно, но что поделать... Скоро загрузчик с SD-карты напишу, будет веселее. От компа с RS-232 стоит преобразователь лог-уровней MAX3232 и на UART C6745-го. Индусы делают на своих платах через FT232 (USB-UART). Тоже начинал отлаживаться со светодиода, тест SDRAM был со светодиодом) Позже прикрутил LCD, теперь его использую в качестве индикатора при отладке - можно сразу кучу данных показать. Правда традиция диктует использовать UART и терминалку для этого, но исторически сложилось так, что дисплей подключил первее и UART-отладка потеряла смысл )) По исследованиям C6745 создал целую тему здесь: http://vrtp.ru/index.php?showtopic=30775&st=0 Но там больше на монолог похоже - сам с собой разговариваю!) Драфт-схема отладочной платы на C6745 (резисторы на BOOT-пинах изменены: 1 кОм на +3.3V, 220 Ом на GND. Номиналы резисторов для LDO на 1.3V - вместо 5,6 кОм надо 240 Ом, а вместо 220 Ом надо 10 Ом. ):
  10. У меня была цель сконвертить фрейм в формате YUV 8:8:8 в RGB 5:6:5 размером 400x240. EDMA3 тут не идёт, потому что он только копирует данные без преобразования. А PRUSS могут параллельно конвертить YUV в RGB, но работают быстро только с внутренней памятью. У меня она отдана L1D, L1I и L2 - с включенным кешированием декод MP4 должен ещё хорошо работать. Если же отключить L1, L2 и отдать её PRUSS'ам, то в целом производительность упадёт. Уже кот который раз замечаю, что если часть внутреннего ОЗУ дать кому-нибудь другому, при этом подрезать L2 кеш, то в целом будет только хуже. Но в целом я решение нашёл - построчно копировать в ближнюю память, затем работать с ней PRUSS'ами. Выходит быстрее всего в целом
  11. Доступ ко всей памяти, но БЕЗ кеширования внешней! Проверил, с SDRAM данные тащит медленно. С этим беда у C6745 - в регистрах R30 и R31 нет мультиплексирования на GPIO. Писал об этом выше. На выполнение PRUSS-кода имелось в виду! PRUSS не могут выполнять код за пределами IRAM0, IRAM1 С внешней памятью PRUSS работают крайне медленно, так как не используют кеширования. Весь разбор полётов надо делать с внутренней памяти, предварительно забуферизовав строку с внешней во внутреннюю память (писал выше - прирост в скорости 22 %). Потому что я использую PRU0. PRU1 пока отключено и не используется.
  12. У C6745 с PRUSS'ами всё более плачевно - нет мэппинга на GPO,GPI - а это значит реалтаймовский ногодрыг на нём не сделаешь. Во всяком случае в мануале на C6754 нет в PINMUX'ах упоминания что можно использовать GPIO для PRUSS'ов. У 6748-го уже есть. Но есть возможность сделать ногодрыг через Global Register Area, но это будет медленно. Ну и 4 кБ памяти кода (всего 1024 команды) и 1 кБ памяти данных (ближняя, быстрая) - сильно с-ужают круг допустимых задач. Тем не менее, как графический ускоритель - конвертер-фильтр он годится! Вырисовываются такие задачи для PRUSS: 1) Конвертер YUV в RGB => отрисовка на дисплей 2) Конвертер палитровых 256 цветов в 16 бит => отрисовка 3) Смарт-фильтры для 2D-графики (Eagle, Sai2x, HQ2x, LQ2x,.... в ранних темах писал и выкладывал) => отрисовка 4) Up-Скейлер, Down-скейлер, отрисовка с поворотом. Почти как DMA, но ещё и с попиксельным процессингом! Аля пиксельный шейдер! ))) А что за там ускоритель? Если 2D, то фтопку, DMA же есть, на нём делается Bit-Blt. Если 3D, то может посмотреть в сторону Фуджитсы с открытым 3D-ускорителем ? (Fujitsu Crimson, Scarlet, некоторые имеют встроенную память). Текстурированные перспективно-корректные треугольники со смуффингом там поддерживаются. Как же уже достало меня это говно! Его только под линуксом с пыхтоном в паре пускать... Баре-металом там даже и не пахнет. И под линуксом если что - драйвера на видео-часть в виде блобов, свободой там даже и не пахнет. Не пробовал )) Хотя возможность рисования и компиляции схем в Квартусе есть. Писал на VHDL'e дизайн видеокарты 11 лет назад. Успешно, понравилось. Сейчас уже ничего не помню! Хотя при желании за 3 дня восстановлю навыки.
  13. Я не настолько хорошо знаю ассемблер PRUSS'ов, проще наверное получить асм-листинг и потом с ним работать. И всё-же моя мечта чтобы компилятор C жмяхал код настолько сильно , насколько это возможно. Код должен быть буквально "лысым" - ничего лишнего, только по делу. Часть регистров отвести под константы разные, чтоб не перезагружать данные. Ещё один прикол с CLPRU: вызов функции memcpy() компилятор инлайнит в пару бурстов LBBO/SBBO, что радует
  14. Удалось поднять производительность отрисовки PRUSS на 22,6 %. Увеличение получено с помощью копирования компонент Y,U,V каждой строки из дальней памяти во внутреннюю память PRUSS'а. Копирую блоками по 8 байт, хотя LBB0,SBB0 позволяют до 124 байт скопировать - но выше 8 байт бурст делать нет смысла - на производительность уже не влияет. Ниже усовершенствованный код:
  15. Асм-листинг во что это компилируется ниже: main.asm
  16. Даташит - необходимое, но ещё недостаточное условие для успешного взлёта. Необходимы App Notes от самого производителя - конкретно по каждой периферии. Чтобы были: порядок инициализации и несколько частных случаев как работать с узлом. Одного описания регистров с разбитовкой крайне мало. Поэтому приходится смотреть сорцы ситары с бигл-бонами :) Ну и ОМАРы тоже помогают (L137). Правда там всё на калокубе CSL'е, но всёравно нагромождения присутствуют. Пока развернёшь вручную макросы - мозги на бекрень поедут ))) А структуры с указателями на другие структуры, которые указывают на другие структуры...... и всё для того чтоб доползти до конкретного бита. Усложнения!
  17. Поздравляю с успешным запуском "гравицапы" ! :) У меня сейчас аналогичные дела - курю C6745, там тоже в большей части всё загадочно. Но курение даташитов + огрызки сорцов под CSL + ситары с бигл-бонами - делают своё дело! Нынче поколения эмбедеров пошло уже не то - Линуксы и кало-Кубы им подавай... Да, они словят "culture shock" от чтения мануалов, деградация поколений пошла. Я пока раскуривал мануалы на EDMA3 и McASP чуть мозг не свернул - реально потом нервы шалить стали (вынужден был на успокоительном сидеть), такая сильная увлеченность "excited"! )) Представляю что будет, если копнуть камень по-сложнее и с котороым полная задница в плане документации и примеров программирования (за минусом Линукса и ведра) - Alwinner A13, V3s :)))
  18. Ну что, други! :))) Проблема успешно решена уже в третьей теме самостоятельно! Форум умер или вопрос теребует сверх-компетенции? Проблема была в силиконовой версии Run-time библиотеки. Надо ставить самую первую: rtspruv1_le.lib - с ней всё заработало. v2,v3 не идут с C6745. (rtspruv2_le.lib и rtspruv3_le.lib) Сравнил бинарные образы - да, различаются несколько байт. Вполне возможно что допустимо в поздних силиконовых ревизиях - недопустимо в первой. Для проверки работы PRU вот такой код использую: void delay(volatile unsigned int d) { while(d--); } void main(void) { delay(10000000); __halt(); } Что даёт задержку на доли секунды. Двоичный образ кода: #pragma DATA_ALIGN(PRU_CODE,4) const u8 PRU_CODE[0x1000]= { 0xc0, 0x00, 0x00, 0x24, 0x80, 0x80, 0x00, 0x24, 0xe2, 0xe0, 0x04, 0x05, 0xee, 0x00, 0x00, 0x24, 0xc3, 0x16, 0x00, 0x23, 0xee, 0x01, 0x00, 0x24, 0xc3, 0x1c, 0x00, 0x23, 0xe2, 0xe2, 0x04, 0x05, 0x8e, 0x22, 0x00, 0xe1, 0x80, 0x22, 0x00, 0xf1, 0xe0, 0xe0, 0x01, 0x05, 0x80, 0x22, 0x00, 0xe1, 0x00, 0x10, 0x00, 0x21, 0x80, 0x22, 0x00, 0xf1, 0xe0, 0xe0, 0x01, 0x05, 0x80, 0x22, 0x00, 0xe1, 0xc0, 0xff, 0xff, 0x24, 0x80, 0xff, 0xff, 0x24, 0x81, 0x22, 0x00, 0xf1, 0xfa, 0xe0, 0xe1, 0x6e, 0xe2, 0xe2, 0x04, 0x01, 0x00, 0x00, 0xc3, 0x20, 0x83, 0xc3, 0xc3, 0x10, 0xce, 0x98, 0x00, 0x24, 0x8e, 0x80, 0x96, 0x24, 0xc3, 0x07, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x83, 0x20, 0xc3, 0x1e, 0x00, 0x23, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xc3, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //....дальше нули };
  19. Запустил EDMA3 в C6745 и программно проверяю конец передачи, чтобы не начать раньше следующую. Код: #define ACNT_MAX 65535 /* Если размер блока превышает это значение, то будет 2D DMA, иначе 1D DMA */ void EDMA3_Init(void *s,u32 n) { register u32 A=n,B=1; //1D DMA while(1) //2D DMA { if((A<=ACNT_MAX)&&(!(n%B)))break; B++; A=n/B; } EDMA3_ESR=0x00000000; //Channel 1 event clear EDMA3_ICR=0x00000001; //Channel 1 interrupt clear PaRAM_OPT=0; PaRAM_SRC=(u32)s; //SRC Address PaRAM_A_CNT=(u16)A; //1..65535 PaRAM_B_CNT=(u16)B; //1..65535 PaRAM_DST=LCD_D; //DST Address (LCD Data Port) PaRAM_SRC_BIDX=(u16)A; //-32786..32767 PaRAM_DST_BIDX=0; PaRAM_LINK=0xFFFF; PaRAM_BCNTRLD=0; PaRAM_SRC_CIDX=0; PaRAM_DST_CIDX=0; PaRAM_CCNT=1; PaRAM_RSVD=0; PaRAM_OPT=(1<<20)|(1<<3)|(1<<2)|(1<<1); //TCINTEN=1, STATIC=1, SYNCDIM=1, DAM=1 EDMA3_IESR=0x00000001; EDMA3_EESR=1; } Запуск ДМА: void EDMA3_Run(void) { EDMA3_ESR=0x00000001; //Channel 1 set } Программная проверка конца передачи: void EDMA_Wait(void) { while(!(EDMA3_IPR&0x00000001)); //Channel 1 interrupt pending EDMA3_ICR=0x00000001; //Channel 1 interrupt clear } Так всё работает. Но при поытке вызвать прервывание от EDMA3 - ничего не происходит, прерывание не вызывается. Код установки прерывания: void EDMA3_INT_Init(void) { INTMUX1=8; //Event #8 => INTSEL4 ISTP=(u32)_intcVectorTable; //set new Vector Table for Interrupt ICR=0xFFF0; //clear all interrupts, bits 4 thru 15 IER|=(1<<4)|(1<<1); //enable INT4, NMI interrupts _enable_interrupts(); } volatile u32 EDMA3_Flag=0; interrupt void EDMA3_INT(void) { LCD_Clear(0x0000); EDMA3_Flag=1; } Вектора: .align 1024 _intcVectorTable: _vector0: VEC_ENTRY _c_int00 ;RESET _vector1: VEC_ENTRY _vec_dummy ;NMI _vector2: VEC_ENTRY _vec_dummy ;RSVD _vector3: VEC_ENTRY _vec_dummy ;RSVD _vector4: VEC_ENTRY EDMA3_INT ;Interrupt4 ISR Ничерта не работает! Нет уверенности в том что на INTMUX сидит правильный номер эвента прерывания от EDMA. Даташит говорит что их целых 4: 8,56,57,58 - ни один не работает. Спецы, помогите, в чем может быть дело ?
  20. Проблема была успешно решена. Причина была в регистре DRAE1 его надо было включить. Только в этом случае прерывания от ДМА будут приходить (Event #8 по дефолту на INT8 в PINMUX2)
  21. В C6745 выводил звук на DAC с помощью McASP + Audio FIFO + EDMA3. Претензий к качеству звука не имеется. McASP тактуется от кварца 24 МГц. Для борьбы с запаздываниями MCLK,BITCLK,FSYNC - правильно выбрать источники сигналов (всё брал относительно ноги MCLK) - иначе грязно будет играть. По идее, AUDIO FIFO должен обеспечить запас для непрерывности воспроизведения звука, в случае подгрузки данных по прерываниям или DMA в буфера. ADSP21489 имеет FIFO, DMA ?
  22. И снова здравствуйте! Реализую билинейную фильтрацию, алгоритм отладил. Теперь хочу перенести его на SIMD инструкции. Исходные цветовые компоненты хранятся в памяти так: 0:R:G:B= 8:8:8:8 бит Текстура 128x128 Необходимо в реальном времени считать билинейную фильтрацию. Работа с четыремя исходными пикселями. Алгоритм такой: #define FRAC(x) _fabsf((x)-((float)_spint(x))) /* Дробная часть. Есть ли intrising Для C6745 ??? */ #define MIX(A,B,t) (((t)*(B))+((1.0F-(t))*(A))) /* Интерполяция. Интрисинк есть??? */ //Тело цыкла: register float rz=_rcpsp(z); register float p=v*rz; register float q=u*rz; register s32 sp=_spint(p); register s32 sq=_spint(q); register s32 t00=pt[(( sp &(MaxU-1))*MaxU)+( sq &(MaxV-1))]; //исходные 4 пиксела в формате 0RGB по 8 бит каждый register s32 t01=pt[(( sp &(MaxU-1))*MaxU)+((sq+1)&(MaxV-1))]; register s32 t10=pt[(((sp+1)&(MaxU-1))*MaxU)+( sq &(MaxV-1))]; register s32 t11=pt[(((sp+1)&(MaxU-1))*MaxU)+((sq+1)&(MaxV-1))]; register float A=FRAC(p); register float B=FRAC(q); register float q0r; register float q0g; register float q0b; register float q1r; register float q1g; register float q1b; if(sp>0) { q0r=MIX((float)( t00>>16 ),(float)( t10>>16 ),A); //Покомпонентно интерполируем по X: top и bottom q0g=MIX((float)((t00>> 8)&0xFF),(float)((t10>> 8)&0xFF),A); q0b=MIX((float)( t00 &0xFF),(float)( t10 &0xFF),A); q1r=MIX((float)( t01>>16 ),(float)( t11>>16 ),A); q1g=MIX((float)((t01>> 8)&0xFF),(float)((t11>> 8)&0xFF),A); q1b=MIX((float)( t01 &0xFF),(float)( t11 &0xFF),A); } else { q0r=MIX((float)( t10>>16 ),(float)( t00>>16 ),A); q0g=MIX((float)((t10>> 8)&0xFF),(float)((t00>> 8)&0xFF),A); q0b=MIX((float)( t10 &0xFF),(float)( t00 &0xFF),A); q1r=MIX((float)( t11>>16 ),(float)( t01>>16 ),A); q1g=MIX((float)((t11>> 8)&0xFF),(float)((t01>> 8)&0xFF),A); q1b=MIX((float)( t11 &0xFF),(float)( t01 &0xFF),A); } register float q2r; register float q2g; register float q2b; if(sq>0) { q2r=MIX(q0r,q1r,B); //Покомпонентно интерполируем по Y q2g=MIX(q0g,q1g,B); q2b=MIX(q0b,q1b,B); } else { q2r=MIX(q1r,q0r,B); q2g=MIX(q1g,q0g,B); q2b=MIX(q1b,q0b,B); } *vb++=((_spint(q2r)&0xF8)<<8)|((_spint(q2g)&0xFC)<<3)|(_spint(q2b)>>3); //Собираем итоговый пиксел с конверсией 0:8:8:8 в 5:6:5 z=z+dz; u=u+du; v=v+dv; Есть ли интрисинки чтоб на SIMD переложить алгоритм для 6545-го ? Надо чтоб с 4 float работал (умножение сложение) и с 4 int ещё _x128_t для C6745 не поддерживается даже со включенным <c6x.h>
  23. Видео. Как-то так. Разрешение 400x240. Мигрировал на другой дисплей, более лучшего качества матрицы: https://www.youtube.com/watch?v=sBq2i1dVWh8
  24. TMS320C6745 Выжал 88 кадров в секунду с реалтайм билинейной фильтрации. При этом формат пикселя 8:8:8 конвертится на лету в 5:6:5 и кидается DMA на дисплей. Всю программу и текстуру 128x128 32 bit per pixel - расположил в L2. Кеш 2 evtymibk c 256 кБ до 128 кБ. Во внешней SDRAM только 2 видеобуфера - один читает DMA в другой рендерит CPU. Без размещения текстуры во внутреней памяти было 80 кадров в секунду (зато кеш L2 в 2 раза больше доступен ) - +8 FPS прибавка . Долго не мог реализовать возврат дробной части вещественного числа - вначале делал так: _fabs(x - (float)_spint(x)) - была лажа местами из-за ошибок точности. Позже свой вариант написал - весьма заумный. Текст программы ниже - кадр 400 x 240 16 bpp - даёт 88 кадров в секунду с реал-тайм билинейной фильтрацией текстуры 128x128 32bit. union tc { u32 t; u8 c[4]; }; #pragma DATA_ALIGN(t0,4) union tc t0; #pragma DATA_ALIGN(t1,4) union tc t1; #pragma DATA_ALIGN(t2,4) union tc t2; #pragma DATA_ALIGN(t3,4) union tc t3; inline void Line(void) { register s32 a=_spint(x1); register s32 b=_spint(x2); //............... register u16 * restrict vb=(u16*)(SwitchBuffer[0]+(((y*MaxX)+a)<<1)); register u32 const * restrict pt=(u32 const*)TUNNEL; b-=a-1; _nassert(b>=2); #pragma MUST_ITERATE(2,,) do { register float rz=_rcpsp(z); register float p=u*rz; register float q=v*rz; register s32 sp=_spint(p); register s32 sq=_spint(q); register u32 a0=(( sp &(MaxU-1))*MaxU); register u32 a1=(((sp+1)&(MaxU-1))*MaxU); register u32 a2= ( sq &(MaxV-1)); register u32 a3= ((sq+1)&(MaxV-1)); t0.t=pt[a0+a2]; t1.t=pt[a0+a3]; t2.t=pt[a1+a2]; t3.t=pt[a1+a3]; *vb++=((_spint(MIX(MIX(t0.c[2],t2.c[2],p),MIX(t1.c[2],t3.c[2],p),q))&0xF8)<<8)| ((_spint(MIX(MIX(t0.c[1],t2.c[1],p),MIX(t1.c[1],t3.c[1],p),q))&0xFC)<<3)| ( _spint(MIX(MIX(t0.c[0],t2.c[0],p),MIX(t1.c[0],t3.c[0],p),q)) >>3); z=z+dz; u=u+du; v=v+dv; } while(--b); } Как бы ещё чего придумать чтоб быстрее было? И вот это можно написать более оптимальнее? Или может intrinsic есть? #define FRAC(t) (((float)(_spint(/*_fabsf*/(t)*256.0F)&0xFF))*0.00390625F) /* дробная часть : 256 градаций */ #define MIX(A,B,t) ((((B)-(A))*FRAC(t))+(A)) /* Интерполяция */
  25. Делаю расчёты в формате floating point. К примеру - делю одно на другое. В асм-листинге вижу такое: $C$RL64: ; CALL OCCURS {__c6xabi_divf} {0} ; [] |147| ;** --------------------------------------------------------------------------* CALLP .S2 __c6xabi_divf,B3 ; [B_Sb674] |147| Как это безобразие называется??? Аппаратная поддержка floating point? C6745 вообще поддерживает операции с плавающей точкой или нет? Я ожидал инлайнинга иструкций на ассемблере, а не вызов функций с черт-пойми каким содержимым. Как итог: программа тормозит, и скорее всего там идёт целочисленная эмуляция плавучки. Спецы, подскажите, как заставить генериться код с ассемблерными инструкциями плавучки?