Перейти к содержанию
    

Проблемка с IAR 6.30.1 для Cortex

Попробовал IAR 6.30.1 для Cortex-M3, нарисовалась проблема.

Есть такой код:

#define	b0_l(L)	((unsigned char)((L)       & 0xFF))
#define	b1_l(L)	((unsigned char)(((L)>>8)  & 0xFF))
#define	b2_l(L)	((unsigned char)(((L)>>16) & 0xFF))
#define	b3_l(L)	((unsigned char)(((L)>>24) & 0xFF))

unsigned long IsDate(unsigned long d)
{
 if (  (b0_l(d)<1)  || (b0_l(d)>31)
    || (b1_l(d)<1)	|| (b1_l(d)>12)
    || (b2_l(d)>21)	|| (b3_l(d)!=0))
 {
   return 0;
 }
 if (d == 0x101)
 {
   return 0;
 }
 return 1;
}

Функция просто предварительно проверяет значение даты, упакованной в unsigned long.

При наличии ключей оптимизации -Om (или -Ohz, другую не пробовал) превращается в такое:

   \                                 In section .text, align 2, keep-with-next
    49          unsigned long IsDate(unsigned long d)
    50          {
    51          	if	(  (b0_l(d)<1)  || (b0_l(d)>31)
    52          		|| (b1_l(d)<1)	|| (b1_l(d)>12)
    53          		|| (b2_l(d)>21)	|| (b3_l(d)!=0))
  \                     IsDate:
  \   00000000   0x1E41             SUBS     R1,R0,#+1
  \   00000002   0x291F             CMP      R1,#+31
  \   00000004   0xBF3E             ITTT     CC 
  \   00000006   0x0A01             LSRCC    R1,R0,#+8
  \   00000008   0x1E49             SUBCC    R1,R1,#+1
  \   0000000A   0x290C             CMPCC    R1,#+12
  \   0000000C   0xBF3E             ITTT     CC 
  \   0000000E   0x0C01             LSRCC    R1,R0,#+16
  \   00000010   0xB2C9             UXTBCC   R1,R1
  \   00000012   0x2916             CMPCC    R1,#+22
  \   00000014   0xD205             BCS.N    ??IsDate_0
  \   00000016   0x0E01             LSRS     R1,R0,#+24
  \   00000018   0xD103             BNE.N    ??IsDate_0
    54          	{
    55          		return 0;
    56          	}
    57          	if (d == 0x101)
  \   0000001A   0xF240 0x1101      MOVW     R1,#+257
  \   0000001E   0x4288             CMP      R0,R1
  \   00000020   0xD101             BNE.N    ??IsDate_1
    58          	{
    59          		return 0;
  \                     ??IsDate_0:
  \   00000022   0x2000             MOVS     R0,#+0
  \   00000024   0x4770             BX       LR
    60          	}
    61          	return 1;
  \                     ??IsDate_1:
  \   00000026   0x2001             MOVS     R0,#+1
  \   00000028   0x4770             BX       LR               ;; return
    62          }

 

И не работает правильно.

На версии 5.41 компилируется в рабочий код. Вопрос такой - это я C плоховато знаю или таки глюк компилятора?

upd: привел пример к стандартным типам (убрал typedef свои), чтобы не путались

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да - в оптимизации явно глюк!

Возможно связан с тем что в макросе лишняя операция :

& 0xff

и

(unsigned char) преобразование типа к байту

 

можно оставить что то одно!

Лучше убрать (unsigned char) так производительность выше!

Потому что если локальная переменная в регистре байтовая ей ARM компилер постоянно чистит старшие биты!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да - в оптимизации явно глюк!

Возможно связан с тем что в макросе лишняя операция :

& 0xff

и

(unsigned char) преобразование типа к байту

 

можно оставить что то одно!

Да, если убрать преобразование типа (unsigned char) в макросах, то именно это место компилируется правильно. Беда в том, что этим макросам лет 20, и страшно представить сколько кода на данный момент на них основано - для 8-битных AVR, 16-битных x86 и для 32-битных ARM. Поэтому поменять макросы малореально.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может расскажете, где именно в дизассемблере неправильно? Я смотрел, но ничего особенного не увидел...

 

Update:

Кажется, увидел. На первой же инструкции делает вычитание из 32-битного аргумента, а должен был сначала отрезать старшие 24 бита.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8-битных AVR, 16-битных x86 и для 32-битных ARM. Поэтому поменять макросы малореально.

Есть же

#ifdef

 

к тому же если убрать одну из операций, оптимальнее преобразование типа - макросы все равно будут рабочими и более оптимальными.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть же #ifdef

к тому же если убрать одну из операций, оптимальнее преобразование типа - макросы все равно будут рабочими и более оптимальными.

1. Убирание "& 0xFF" ситуацию не исправляет - компилируется с той же ошибкой, глючит именно на unsigned char.

2. #ifdef не поможет скомпилировать желаемое для выражений подразумевающих что макрос bx_l() имеет тип unsigned char. То есть - эти выражения все надо будет патчить в куче мест, вставляя явное приведение типа (которое Вы предлагаете выбросить из макроса). Пример - код типа: "unsigned char var1 = b0_l((unsigned long)var2);" даст предупреждение.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Убирание "& 0xFF" ситуацию не исправляет - компилируется с той же ошибкой, глючит именно на unsigned char.

2. #ifdef не поможет скомпилировать желаемое для выражений подразумевающих что макрос bx_l() имеет тип unsigned char. То есть - эти выражения все надо будет патчить в куче мест, вставляя явное приведение типа (которое Вы предлагаете выбросить из макроса). Пример - код типа: "unsigned char var1 = b0_l((unsigned long)var2);" даст предупреждение.

 

Основная проблема не в том, что определенными телодвижениями можно замести это под ковер, и заставить код работать правильно. А в том, что этот код правильно компилировался десятком разных компиляторов, начиная с BC3.1 и заканчивая IAR 5.41. И не факт, что где-нибудь компилятор не оставит незаметную мину, которая сработает в очень редко вызываемой ветке программы в самый неподходящий момент.

 

Пока от версии IAR 6.30 пришлось отказаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а у IAR периодически вылезают баги с количеством битов при преобразованиях типов и &

скоро вылечат!

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...