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

 
 
> IAR ARM ассемблер, Преобразовать процедуру в макрос
Sergey_Aleksandr...
сообщение Aug 28 2017, 13:42
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Здравствуйте. В проекте функция реализована как ассемблерная процедура. Состоит из одной инструкции и хотелось бы преобразовать её в макрос, чтобы не тратить такты на вход и выход.
Реализована в *.s файле в виде
Код
    SECTION .text:CODE:NOROOT(2)
    PUBLIC MULSHIFT32
    THUMB
MULSHIFT32
    smull    r2, r0, r1, r0
    BX lr

Далее используется в *.c файлах как обычная функция b2 = MULSHIFT32(*cptr++, a1 - a2) << (s1);

Не зная тонкостей синтаксиса ассемблера IAR попробовал "в лоб" реализовать таким образом
Код
MULSHIFT32 MACRO
    smull    r2, r0, r1, r0
    ENDM


Линкер ругается на неизвестное имя MULSHIFT32. Ключевые слова PUBLIC и EXTERN вызывают ошибку. Кто подскажет, как этот макрос правильно оформить, чтобы можно было использовать его вне *.s-файла?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
VladislavS
сообщение Aug 31 2017, 03:58
Сообщение #2


Местный
***

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



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


Гуру
******

Группа: Свой
Сообщений: 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
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 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
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 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

Сообщений в этой теме
- Sergey_Aleksandrovi4   IAR ARM ассемблер   Aug 28 2017, 13:42
- - VladislavS   Не занимайтесь ерундой. Умножать с нужной разрядно...   Aug 28 2017, 14:01
|- - Sergey_Aleksandrovi4   VladislavS, спасибо за идею. Это не совсем то, что...   Aug 28 2017, 14:43
|- - jcxz   Цитата(Sergey_Aleksandrovi4 @ Aug 28 2017, 17...   Aug 28 2017, 15:49
- - scifi   Из любопытства попробовал на GCC вот такое: Код#de...   Aug 28 2017, 15:18
- - VladislavS   Во-первых, очень некрасиво не показывать типы испо...   Aug 28 2017, 16:00
|- - jcxz   Цитата(VladislavS @ Aug 28 2017, 19:00) П...   Aug 28 2017, 16:04
- - VladislavS   Дарю Код#define MULSHIFT32(arg1, arg2) ...   Aug 28 2017, 16:14
|- - jcxz   Цитата(VladislavS @ Aug 28 2017, 19:14) Д...   Aug 30 2017, 08:26
- - scifi   Кстати, если в моём эксперименте с GCC сделать так...   Aug 29 2017, 09:41
- - Sergey_Aleksandrovi4   jcxz, всё верно, чужие библиотеки. Портирую mp3-де...   Aug 29 2017, 09:53
|- - jcxz   Цитата(Sergey_Aleksandrovi4 @ Aug 29 2017, 12...   Aug 29 2017, 10:58
- - scifi   Цитата(Sergey_Aleksandrovi4 @ Aug 29 2017, 12...   Aug 29 2017, 10:29
- - Sergey_Aleksandrovi4   Цитата(scifi @ Aug 29 2017, 13:29) Это ма...   Aug 29 2017, 13:04
- - VladislavS   Если есть возможность не уходить от чистого С/C++,...   Aug 30 2017, 11:34
|- - scifi   Цитата(VladislavS @ Aug 30 2017, 14:34) К...   Aug 30 2017, 16:28
- - VladislavS   Не надо ничего ловить. Надо правильно применять яз...   Aug 30 2017, 17:58
|- - jcxz   Цитата(VladislavS @ Aug 30 2017, 20:58) С...   Aug 30 2017, 20:18
- - KRS   Так у IAR теперь есть GCC inline assembler так что...   Aug 31 2017, 11:15
|- - Obam   Цитата(KRS @ Aug 31 2017, 15:15) Так у IA...   Aug 31 2017, 14:41
|- - KRS   Цитата(Obam @ Aug 31 2017, 17:41) IAR с G...   Sep 3 2017, 17:13
- - Obam   Да, но не GCC.   Sep 4 2017, 07:36
- - KRS   Цитата(Obam @ Sep 4 2017, 10:36) Да, но н...   Sep 4 2017, 08:10


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

 


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


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