Jump to content

    
Sign in to follow this  
VslavX

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

Recommended Posts

Попробовал 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 свои), чтобы не путались

Share this post


Link to post
Share on other sites

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

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

& 0xff

и

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

 

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

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

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

 

Share this post


Link to post
Share on other sites
Да - в оптимизации явно глюк!

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

& 0xff

и

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

 

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

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

 

Share this post


Link to post
Share on other sites

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

 

Update:

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

Share this post


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

Есть же

#ifdef

 

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

 

 

Share this post


Link to post
Share on other sites
Есть же #ifdef

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

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

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

 

Share this post


Link to post
Share on other sites
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 пришлось отказаться.

Share this post


Link to post
Share on other sites

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

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

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

 

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