реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> IAR ARM ассемблер, Преобразовать процедуру в макрос
scifi
сообщение Aug 30 2017, 16:28
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(VladislavS @ Aug 30 2017, 14:34) *
Компилятор не знал команду smmul или программист не смог ему объяснить что он хочет? Я ставлю на второе.

"Не смог объяснить компилятору" - тоже неоднозначная вещь. Если семантика языка Си не даёт компилятору применить оптимальные инструкции, тогда согласен, лучше допилить исходный код. А если компилятор туповат, и для одинаковых по семантике исходников может генерить как более, так и менее оптимальный код, то ловить вариант, который ему более по душе, - сомнительное занятие.
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Aug 30 2017, 17:58
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Не надо ничего ловить. Надо правильно применять язык. Ну что далеко ходить, пример из этой темы. Надо было перемножить два 32-битных числа, получить 64 битный результат и взять старшие 32 бита. Автор тут же рождает макрос, который перемножает два 64-битных числа. Тут же его последователь на другом компиляторе получает "АдЪ". Хотя, компилятор сделал в точности то что его просили и вовсе он не туповат. Сомневаюсь, что сейчас можно найти туповатый компилятор для ARM. Не так уж много способов записать правильно требуемый алгоритм. Сделайте это, а с остальным компилятор разберётся.

ЗЫ: Я не отрицаю, что есть такие вещи, которые чистым С не описать. Но их ещё поискать надо и чаще всего можно интринсиками обойтись без применения ассемблера в чистом виде.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 30 2017, 20:18
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Aug 30 2017, 20:58) *
Сделайте это, а с остальным компилятор разберётся.
ЗЫ: Я не отрицаю, что есть такие вещи, которые чистым С не описать. Но их ещё поискать надо и чаще всего можно интринсиками обойтись без применения ассемблера в чистом виде.

Искать далеко не надо. Попробуйте-ка к примеру определить номер самого старшего "1"-ного бита в переменной на чистом си. Каков будет размер кода? Сумеете объяснить компилятору на ARM, что можно обойтись одной CLZ?
А такая операция, мне например, частенько бывает нужна.

Аналогично - инструкции с "насыщением".
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Aug 31 2017, 03:58
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Могли бы показать пример кода, где вы CLZ применяете?
Правда, интересно глянуть.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 31 2017, 06:12
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Aug 31 2017, 06:58) *
Могли бы показать пример кода, где вы CLZ применяете?
Правда, интересно глянуть.

А какой смысл? Вы считаете, что сможете вот так прям показать как обойтись без CLZ? biggrin.gif
Видимо разработчики ARM-архитектуры всё-таки считают, что CLZ нужна раз ввели её.

Что-ж... Например в текущем проекте:
1. Во всех местах, где нужно преобразование IP-адреса и маски подсети из формата типа 192.168.1.x/255.255.255.0 в упакованный формат 192.168.1.x/24.
Код
              if (!(j = ReverseByteOrder(JReadIP(member)))) break;
              j1 = CntLeadingZeros(ReverseBitOrder(j));
              if (j1 < 2 || ~j >> j1) break;
              cfgMain.enet.mask = j1;


2. В местах, где нужно преобразовать битовую карту в список значений:
Код
  do {
    addr = 31 - CntLeadingZeros(addrMap);
    WriteNum(&addr, JSON_T_NUM8U);
  } while (addrMap -= 1 << addr);


3. В распаковщике сжатого битового потока:
Код
u16fast TinfData::ReadBits(u8fast n)
{
  u32 i, i0, i1 = tag;
  if (!(i0 = i1 >> n)) {
    i = 31 - CntLeadingZeros(i1);
    u32p8 const *p, *p1 = (u32p8 const *)srcCur;
    if ((u32)(p = p1 + 1) > (u32)srcEnd) TinfFault(ERR_OVERFLOW_SRC);
    srcCur = (u8 const *)p;
    i1 += (i0 = *p1) - 1 << i;
    i0 = (i0 >> 1) + B31;
    i0 >>= n - i - 1;
  }
  tag = i0;
  return i1 - (i0 << n);
}


4. В API разных служб, которые принимают и фиксируют клиентские запросы (в битовой карте) и впоследствии их обрабатывают по мере освобождения службы и в порядке приоритета.

Итого - в десятке мест.
в хидерах:
#define CntLeadingZeros() __CLZ()
#define ReverseBitOrder() __RBIT()

В другом проекте есть например использование CLZ при распарсивании UTF-8 кодировки принимаемой с терминала:
Код
  while ((int)(c = TermGetChar(tout)) >= 0) {
    do {
      if (PARSE_UTF8_DEF && (c & B7)) {
        //преобразование UTF-8 в Win1251
        u32 cc = (u32)c << 25;
        if (j = CntLeadingZeros(~cc)) {
          if (j > 5 || state != S_NONE) return HEsc_ERROR;
          cnt = j;
          j += 26;
          arg = c << j >> j;
          state = S_UTF8;
        } else {
          if (state != S_UTF8) return HEsc_ERROR;
          arg = arg << 6 | cc >> 25;
          if (--cnt) continue;
          c = (cc = arg - 0x410) + 0xC0;
          if (cc > (uint)'я' - (uint)'А') {
            c = 'Ё';
            if (cc += 0x410u - 0x401u) {
              c = 'ё';
              if (cc += 0x401u - 0x451u) return HEsc_SKIP;
            }
          }
          state = S_INIT;
          return (HEsc)c;
        }
      } else if ((c & 0x7F) == 0x1B) {
...
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Aug 31 2017, 07:53
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(jcxz @ Aug 31 2017, 09:12) *
А какой смысл? Вы считаете, что сможете вот так прям показать как обойтись без CLZ? biggrin.gif

Нет, мне реально интересно где и как вы используете CLZ. Спасибо за примеры.

И всё же, я считаю, что надо по максимуму использовать возможности языка для переносимости. Затем интринсики и в самых тяжёлых случаях асм.

UPD: В случае с CLZ с переносимостью как раз полный порядок. Она есть практически во всех процессорах, за исключением всяких 8-биток.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 31 2017, 08:35
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(VladislavS @ Aug 31 2017, 10:53) *
UPD: В случае с CLZ с переносимостью как раз полный порядок. Она есть практически во всех процессорах, за исключением всяких 8-биток.

Но стандартными средствами языка си её как видимо не получить на современном уровне развития компиляторов.
Не настолько они ещё интеллектуальны, чтобы цикл, реализующий функционал CLZ, компилятор заменял на CLZ (хотя - может какие-то уже умеют? 8-)
Вот именно поэтому у меня и есть макрос CntLeadingZeros(), разворачивающийся на ARM в CLZ, на других CPU - в их соответствующие инструкции. Или в циклы, там где нет подобной инструкции.
А ещё недавно и конструкцию (long)((long long)(long)(x) * (long long)(long)(y) >> 32) IAR видимо не догадывался заменить одной командой.
Go to the top of the page
 
+Quote Post
KRS
сообщение Aug 31 2017, 11:15
Сообщение #23


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Так у IAR теперь есть GCC inline assembler
так что можно и inline функции на асме писать.
Go to the top of the page
 
+Quote Post
Obam
сообщение Aug 31 2017, 14:41
Сообщение #24


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(KRS @ Aug 31 2017, 15:15) *
Так у IAR теперь есть GCC inline assembler
так что можно и inline функции на асме писать.

IAR с GNU Compiler Collection?


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
KRS
сообщение Sep 3 2017, 17:13
Сообщение #25


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Obam @ Aug 31 2017, 17:41) *
IAR с GNU Compiler Collection?

Вы документацию смотрели на IAR?
там теперь можно

Код
int Add(int term1, int term2)
{
    int sum;
    asm("add %0,%1,%2"
        : "=r"(sum)
        : "r" (term1), "r" (term2));
    return sum;
}


и такую функцию можно сделать inline
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 4 2017, 07:36
Сообщение #26


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Да, но не GCC.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
KRS
сообщение Sep 4 2017, 08:10
Сообщение #27


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Obam @ Sep 4 2017, 10:36) *
Да, но не GCC.

В доке на IAR теперь указано
"The syntax of an inline assembler statement is (similar to the one used by GNU gcc):"
Но и в самой документации, довольно неплохо описано как им пользоваться.

Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 04:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016