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

Кривой оптимизатор IAR? (IAR V6.21.1.52794/W32 for ARM)

Имеем (Cortex-M3):

s32 c;  //signed int
if ((u32)c < 100000) {   //проверка как unsigned int
  ...
} else {
  if (c >= 0) i += 1;      //проверка как signed int
  i += 1;
}

После компиляции с полной оптимизацией получаем бред:

;if ((u32)c < 100000) {
              LDR.W    R0,??DataTable21_14;; 0x186a0
              CMP      R5,R0
              BCS.N    ??isrTIMER1_13
              ...
              B.N      ??isrTIMER1_14
;} else {
;  if (c >= 0) i += 1;
  ??isrTIMER1_13:
              ADDS     R0,R4,#+1;почему безусловно??? Где IT???
              ...
;  i += 1;
              ADDS     R4,R0,#+1
;}
  ??isrTIMER1_14:
              ...

Куда делось условное исполнение: if (c >= 0) i += 1; ????

 

Если поставить оптимизацию "Low", то всё нормально - эта строка выполняется по условию (с помощью команд перехода).

При компиляции V5.50.0.51878/W32 for ARM тоже всё ок - строка выполняется условно (с помощью команды IT).

IAR-цы добавили новый баг в оптимизатор?

У кого есть IAR более новый - можете проверить - исправлено это или ещё нет?

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


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

Попробовал такой код:

int
test(int c, int i)
{
  if ((unsigned)c < 100000) {   //проверка как unsigned int
  } else {
    if (c >= 0) i += 1;      //проверка как signed int
    i += 1;
  }
  return i;
}

Вроде бы всё правильно скомпилировалось:

  if ((unsigned)c < 100000) {   //i?iaa?ea eae unsigned int
test:
   0x8000040: 0x4a04         LDR.N     R2, ??test_0            ; 0x186a0 (100000)
   0x8000042: 0x4290         CMP       R0, R2
   0x8000044: 0xd303         BCC.N     ??test_1                ; 0x800004e
   if (c >= 0) i += 1;      //i?iaa?ea eae signed int
   0x8000046: 0x2800         CMP       R0, #0
   0x8000048: 0xbf58         IT        PL
   0x800004a: 0x1c49         ADDPL     R1, R1, #1
   i += 1;
   0x800004c: 0x1c49         ADDS      R1, R1, #1
 return i;
??test_1:
   0x800004e: 0x4608         MOV       R0, R1
   0x8000050: 0x4770         BX        LR
   0x8000052: 0xbf00         NOP
??test_0:
   0x8000054: 0x000186a0     DC32      100000                  ; ' †..'

Яр 6.40.1.3832.

 

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


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

Да, Ваш и у меня правильно компилится. И если мою функцию урезать - тоже начинает правильно. Но в изначальном виде - баг!

Приведу функцию в исходном виде (почти как у меня в рабочем варианте). Извините что так много, но при урезании функции начинает нормально компилить. %-\

 

#define WATCH_BASE_CLK 1000000   //[Hz] дискретность nTIM_watch
#define T_ADJ 16  //разрядность фильтра джиттера ISR RTC
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
enum {
 SHIFT_STATE_INIT, SHIFT_STATE_IDLE, SHIFT_STATE_REQ, SHIFT_STATE_ACT,
 SHIFT_STATE_REPORT, SHIFT_STATE_SYNC};
u32 volatile shadowRTC;
u32 shiftPoint, pointTIM;
u16 adjTim;
u8 stateTIM = 0;
u8 shiftState;
s8 shiftSec;
s32 shiftMs;
typedef struct {
 u32 IR;
 u32 TCR;
 u32 TC;
 u32 PR;
 u32 PC;
 u32 MCR;
 u32 MR[4];
 u32 CCR;
 u32 CR[2];
 u32 unuse0[2];
 u32 EMR;
 u32 unuse1[12];
 u32 CTCR;
} HwRegsTIMER;
__no_init extern volatile HwRegsTIMER TIMER_0  @ ".HwRegsTIMER0";

u32 GetMcsTimer() { return TIMER_0.TC; }

extern "C" void TBug()
{
 static s8 secAdd;
 u32 i, j = GetMcsTimer();
 s32 c, cc;
 volatile HwRegsTIMER *p = &TIMER_0;
 p->IR = 2;
 switch (i = stateTIM) {
   case 12: stateTIM = 11; return;
   case 10:
   case 2:
     if ((c = p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
     p->MR[1] = c;
     stateTIM = i + 1;
     return;
   case 11:
     shiftState = SHIFT_STATE_REPORT;
//      PingWatch();
   case 3:
     shadowRTC += secAdd;
     if (stateTIM = i >>= 3) break;
   case 0:
     if (shiftPoint == shadowRTC + 1 && shiftState == SHIFT_STATE_REQ) {
       shiftState = SHIFT_STATE_ACT;
       c = shiftMs;
       cc = shiftSec;
       i = 10;
     }
   case 1:
     if (i < 2) {
       stateTIM = 0;
       if (adjTim & (1 << T_ADJ - 1) - 1) {
         c = adjTim;
         adjTim = cc = 0;
         i = 2;
       } else break;
     }
     secAdd = cc;
     if ((u32)c < WATCH_BASE_CLK / 10) {
       if ((c += p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
       p->MR[1] = c;
     } else {
       if (c >= 0) i += 1;
       if ((c += p->MR[1]) < 0) c += WATCH_BASE_CLK;
       if (c >= WATCH_BASE_CLK) c -= WATCH_BASE_CLK;
       p->MR[1] = c;
       i += 1;
     }
     stateTIM = i;
 }
 pointTIM = j;
 shadowRTC++;
///  PostEventRTC();
}

Вот что получается (см. метки ??TBug_9 и ??TBug_10):

 513		  extern "C" void TBug()
514		{		 
\					TBug:
\   00000000   F8B5			   PUSH	 {R3-R7,LR}
515			static s8 secAdd;
516			u32 i, j = GetMcsTimer();
\   00000002   ........		   BL	   _Z11GetMcsTimerv
517			s32 c, cc;	
518			volatile HwRegsTIMER *p = &TIMER_0;
519			p->IR = B1;
\   00000006   ....			   LDR.N	R2,??DataTable67_11
\   00000008   0221			   MOVS	 R1,#+2
\   0000000A   1160			   STR	  R1,[R2, #+0]
520			switch (i = stateTIM) {
\   0000000C   ....			   LDR.N	R1,??DataTable67_12
\   0000000E   0C78			   LDRB	 R4,[R1, #+0]
\   00000010   0C2C			   CMP	  R4,#+12
\   00000012   52D8			   BHI.N	??TBug_1	
\   00000014   DFE804F0		   TBB	  [PC, R4]
\					 ??TBug_0:
\   00000018   1E2D0A15		   DC8	  0x1E,0x2D,0xA,0x15
\   0000001C   51515151		   DC8	  0x51,0x51,0x51,0x51
\   00000020   51510A13		   DC8	  0x51,0x51,0xA,0x13
\   00000024   0700			   DC8	  0x7,0x0	
521			  case 12: stateTIM = 11; return;
\					 ??TBug_2:
\   00000026   0B20			   MOVS	 R0,#+11	
\					 ??TBug_3:
\   00000028   0870			   STRB	 R0,[R1, #+0]
\   0000002A   F1BD			   POP	  {R0,R4-R7,PC}
522			  case 10:
523			  case 2:
524				if ((c = p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
\					 ??TBug_4:
\   0000002C   D069			   LDR	  R0,[R2, #+28]
\   0000002E   ....			   LDR.N	R3,??DataTable67_13;; 0xfff85ee0
\   00000030   1B18			   ADDS	 R3,R3,R0
\   00000032   44BF			   ITT	  MI
\   00000034   ....			   LDRMI.N  R0,??DataTable67_2;; 0xf4240
\   00000036   C318			   ADDMI	R3,R0,R3	
525				p->MR[1] = c;
\   00000038   D361			   STR	  R3,[R2, #+28]
526				stateTIM = i + 1;
\   0000003A   601C			   ADDS	 R0,R4,#+1
\   0000003C   F4E7			   B.N	  ??TBug_3
527				return;
528			  case 11:
529				shiftState = SHIFT_STATE_REPORT;
\					 ??TBug_5:
\   0000003E   0426			   MOVS	 R6,#+4
\   00000040   4E70			   STRB	 R6,[R1, #+1]
530		  //	  PingWatch();
531			  case 3:
532				shadowRTC += secAdd;
\					 ??TBug_6:
\   00000042   8E68			   LDR	  R6,[R1, #+8]
\   00000044   91F90270		   LDRSB	R7,[R1, #+2]
\   00000048   BE19			   ADDS	 R6,R7,R6
\   0000004A   8E60			   STR	  R6,[R1, #+8]
533				if (stateTIM = i >>= 3) break;
\   0000004C   E408			   LSRS	 R4,R4,#+3
\   0000004E   0C70			   STRB	 R4,[R1, #+0]
\   00000050   0E78			   LDRB	 R6,[R1, #+0]
\   00000052   96BB			   CBNZ.N   R6,??TBug_1
534			  case 0:
535				if (shiftPoint == shadowRTC + 1 && shiftState == SHIFT_STATE_REQ) { 
\					 ??TBug_7:
\   00000054   CE68			   LDR	  R6,[R1, #+12]
\   00000056   8F68			   LDR	  R7,[R1, #+8]
\   00000058   7F1C			   ADDS	 R7,R7,#+1
\   0000005A   BE42			   CMP	  R6,R7
\   0000005C   09D1			   BNE.N	??TBug_8	
\   0000005E   4E78			   LDRB	 R6,[R1, #+1]
\   00000060   022E			   CMP	  R6,#+2
\   00000062   06D1			   BNE.N	??TBug_8
536				  shiftState = SHIFT_STATE_ACT;
\   00000064   0323			   MOVS	 R3,#+3
\   00000066   4B70			   STRB	 R3,[R1, #+1]
537				  c = shiftMs;
\   00000068   4B69			   LDR	  R3,[R1, #+20]
538				  cc = shiftSec;
\   0000006A   91F90650		   LDRSB	R5,[R1, #+6]
539				  i = 10;
\   0000006E   0A24			   MOVS	 R4,#+10	
\   00000070   09E0			   B.N	  ??TBug_9
540				}	   
541			  case 1:
542				if (i < 2) {
\					 ??TBug_8:
\   00000072   022C			   CMP	  R4,#+2	
\   00000074   07D2			   BCS.N	??TBug_9	
543				  stateTIM = 0;
\   00000076   0023			   MOVS	 R3,#+0
\   00000078   0B70			   STRB	 R3,[R1, #+0]
544				  if (adjTim & (1 << T_ADJ - 1) - 1) {
\   0000007A   8B88			   LDRH	 R3,[R1, #+4]
\   0000007C   5C04			   LSLS	 R4,R3,#+17
\   0000007E   1CD0			   BEQ.N	??TBug_1	
545					c = adjTim;
546					adjTim = cc = 0;
\   00000080   0025			   MOVS	 R5,#+0
\   00000082   8D80			   STRH	 R5,[R1, #+4]
547					i = 2;
\   00000084   0224			   MOVS	 R4,#+2
548				  } else break;
549				}	   
550				secAdd = cc;
\					 ??TBug_9:
\   00000086   8D70			   STRB	 R5,[R1, #+2]
551				if ((u32)c < WATCH_BASE_CLK / 10) {
\   00000088   ....			   LDR.N	R5,??DataTable67_14;; 0x186a0
\   0000008A   AB42			   CMP	  R3,R5
\   0000008C   08D2			   BCS.N	??TBug_10
552				  if ((c += p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
\   0000008E   D569			   LDR	  R5,[R2, #+28]
\   00000090   EB18			   ADDS	 R3,R5,R3
\   00000092   ....			   LDR.N	R5,??DataTable67_13;; 0xfff85ee0
\   00000094   EB18			   ADDS	 R3,R5,R3
\   00000096   44BF			   ITT	  MI
\   00000098   ....			   LDRMI.N  R5,??DataTable67_2;; 0xf4240
\   0000009A   EB18			   ADDMI	R3,R5,R3	
553				  p->MR[1] = c;
\   0000009C   D361			   STR	  R3,[R2, #+28]
\   0000009E   0BE0			   B.N	  ??TBug_11
554				} else {
555				  if (c >= 0) i += 1;
\					 ??TBug_10:
\   000000A0   641C			   ADDS	 R4,R4,#+1
556				  if ((c += p->MR[1]) < 0) c += WATCH_BASE_CLK;
\   000000A2   D569			   LDR	  R5,[R2, #+28]
\   000000A4   EB18			   ADDS	 R3,R5,R3
\   000000A6   ....			   LDR.N	R5,??DataTable67_2;; 0xf4240
\   000000A8   48BF			   IT	   MI
\   000000AA   EB18			   ADDMI	R3,R5,R3	
557				  if (c >= WATCH_BASE_CLK) c -= WATCH_BASE_CLK;
\   000000AC   AB42			   CMP	  R3,R5
\   000000AE   A4BF			   ITT	  GE
\   000000B0   ....			   LDRGE.N  R5,??DataTable67_5;; 0xfff0bdc0
\   000000B2   EB18			   ADDGE	R3,R5,R3	
558				  p->MR[1] = c;
\   000000B4   D361			   STR	  R3,[R2, #+28]
559				  i += 1;
\   000000B6   641C			   ADDS	 R4,R4,#+1
560				}	   
561				stateTIM = i;
\					 ??TBug_11:
\   000000B8   0C70			   STRB	 R4,[R1, #+0]
562			}	   
563			pointTIM = j;
\					 ??TBug_1:
\   000000BA   0861			   STR	  R0,[R1, #+16]
564			shadowRTC++;
\   000000BC   8868			   LDR	  R0,[R1, #+8]
\   000000BE   401C			   ADDS	 R0,R0,#+1
\   000000C0   8860			   STR	  R0,[R1, #+8]
565		  ///  PostEventRTC();
566		  }	 
\   000000C2   F1BD			   POP	  {R0,R4-R7,PC}  ;; return

 

Можете это попробовать скомпилить? Скопировал сюда вроде все необходимые define и определения типов.

Изменено пользователем IgorKossak
концевые табы!!!

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


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

Можете это попробовать скомпилить? Скопировал сюда вроде все необходимые define и определения типов.

Попробовал - не компилится, причём по очевидным причинам. Если сделаете пример, который действительно можно вставить в пустой проект и скомпилировать, тогда попробую.

 

Update:

Да, и здесь принято длинные куски кода заворачивать в теги CODEBOX. Не напрягайте модераторов без необходимости - подкорректируйте сами.

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


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

Куда делось условное исполнение: if (c >= 0) i += 1; ????

 

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

 

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


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

Создал пустой проект, скомпилил, цепляю сюда аттачем. SRC.2.ZIP

 

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

Во-первых: используется, смотрите внимательнее.

Во-вторых: не выкинул, а сделал безусловным, смотрите внимательнее.

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


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

Во-первых: используется, смотрите внимательнее.

Судя по этому коду ничего не видно т.к. не видно где используется i .

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


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

Видно:

 561                stateTIM = i;                                                       
\                     ??TBug_11:                                                        
\   000000B8   0C70               STRB     R4,[R1, #+0]

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


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

Семён Семёныч!

У вас прямо перед сравнением переменная 'c' получает значение переменной adjTim, которая имеет тип u16. То есть при сравнении переменная 'c' заведомо неотрицательная.

Не нужно писать такой жуткий код, тогда будете в нём меньше путаться. Я думаю, в такой программе вылезет ещё не один сюрприз. Не спешите винить компилятор.

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


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

Семён Семёныч!

У вас прямо перед сравнением переменная 'c' получает значение переменной adjTim, которая имеет тип u16. То есть при сравнении переменная 'c' заведомо неотрицательная.

Не нужно писать такой жуткий код, тогда будете в нём меньше путаться. Я думаю, в такой программе вылезет ещё не один сюрприз. Не спешите винить компилятор.

Где заведомо? Вы что-то путаете ;)

А Вы видите if (i < 2) немного выше и c = shiftMs; ?

Да, кстати, Вы совершенно правы - при минимизации исходника и обрезки всего, перепутал тип adjTim. Он в оригинале: s16. Но это роли не играет.

Так как значение c может быть присвоено ранее.

Вобщем, по алгоритму, на входе в злополучное сравнение, переменная c может принимать любое значение из диапазона: -2^31...2^31-1.

А насчёт жуткости - Вы видимо не видели по настоящему жутких исходников ;)

 

Ближе к телу: Вы пробовали скомпилить это на Вашем компиляторе?

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


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

Где заведомо? Вы что-то путаете ;)

А Вы видите if (i < 2) немного выше и c = shiftMs; ?

Да, действительно, case 0 я и не приметил.

 

А насчёт жуткости - Вы видимо не видели по настоящему жутких исходников ;)

Надеюсь, больше никогда и не увижу :-)

 

Ближе к телу: Вы пробовали скомпилить это на Вашем компиляторе?

Нет сил анализировать этот шедевр, так что наличие бага не могу ни подтвердить, ни опровергнуть.

Если что, вот что нагенерил компилятор у меня:

      1          #define WATCH_BASE_CLK 1000000   //[Hz] дискретность nTIM_watch
     2          #define T_ADJ 16  //разрядность фильтра джиттера ISR RTC
     3          typedef signed char s8;
     4          typedef signed short s16;
     5          typedef signed int s32;
     6          typedef signed long long s64;
     7          typedef unsigned char u8;
     8          typedef unsigned short u16;
     9          typedef unsigned int u32;
    10          typedef unsigned long long u64;
    11          enum {
    12            SHIFT_STATE_INIT, SHIFT_STATE_IDLE, SHIFT_STATE_REQ, SHIFT_STATE_ACT,
    13            SHIFT_STATE_REPORT, SHIFT_STATE_SYNC};
    14          u32 volatile shadowRTC;
    15          u32 shiftPoint, pointTIM;
    16          u16 adjTim;
    17          u8 stateTIM = 0;
    18          u8 shiftState;
    19          s8 shiftSec;
    20          s32 shiftMs;
    21          typedef struct {
    22            u32 IR;
    23            u32 TCR;
    24            u32 TC;
    25            u32 PR;
    26            u32 PC;
    27            u32 MCR;
    28            u32 MR[4];
    29            u32 CCR;
    30            u32 CR[2];
    31            u32 unuse0[2];
    32            u32 EMR;
    33            u32 unuse1[12];
    34            u32 CTCR;
    35          } HwRegsTIMER;
    36          __no_init extern volatile HwRegsTIMER TIMER_0  @ ".HwRegsTIMER0";
    37          

  \                                 In section .text, align 2, keep-with-next
    38          u32 GetMcsTimer() { return TIMER_0.TC; }
  \                     _Z11GetMcsTimerv:
  \   00000000   0x....             LDR.N    R0,??DataTable1
  \   00000002   0x6880             LDR      R0,[R0, #+8]
  \   00000004   0x4770             BX       LR               ;; return
    39          

  \                                 In section .text, align 4, keep-with-next
    40          extern "C" void TBug()
    41          {
  \                     TBug:
  \   00000000   0xB4F0             PUSH     {R4-R7}
    42            static s8 secAdd;
    43            u32 i, j = GetMcsTimer();
  \   00000002   0x....             LDR.N    R1,??DataTable1
  \   00000004   0x688B             LDR      R3,[R1, #+8]
    44            s32 c, cc;
    45            volatile HwRegsTIMER *p = &TIMER_0;
    46            p->IR = 2;
  \   00000006   0x2002             MOVS     R0,#+2
  \   00000008   0x6008             STR      R0,[R1, #+0]
    47            switch (i = stateTIM) {
  \   0000000A   0x....             LDR.N    R0,??DataTable1_1
  \   0000000C   0x7804             LDRB     R4,[R0, #+0]
  \   0000000E   0x2C0C             CMP      R4,#+12
  \   00000010   0xD854             BHI.N    ??TBug_1
  \   00000012   0xE8DF 0xF004      TBB      [PC, R4]
  \                     ??TBug_0:
  \   00000016   0x20 0x2F          DC8      0x20,0x2F,0x9,0x16
  \              0x09 0x16    
  \   0000001A   0x53 0x53          DC8      0x53,0x53,0x53,0x53
  \              0x53 0x53    
  \   0000001E   0x53 0x53          DC8      0x53,0x53,0x9,0x14
  \              0x09 0x14    
  \   00000022   0x07 0x00          DC8      0x7,0x0
    48              case 12: stateTIM = 11; return;
  \                     ??TBug_2:
  \   00000024   0x210B             MOVS     R1,#+11
  \   00000026   0xE007             B.N      ??TBug_3
    49              case 10:
    50              case 2:
    51                if ((c = p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
  \                     ??TBug_4:
  \   00000028   0x69CA             LDR      R2,[R1, #+28]
  \   0000002A   0x....             LDR.N    R3,??DataTable1_2  ;; 0xfff85ee0
  \   0000002C   0x189A             ADDS     R2,R3,R2
  \   0000002E   0xBF44             ITT      MI 
  \   00000030   0x....             LDRMI.N  R3,??DataTable1_3  ;; 0xf4240
  \   00000032   0x189A             ADDMI    R2,R3,R2
    52                p->MR[1] = c;
  \   00000034   0x61CA             STR      R2,[R1, #+28]
    53                stateTIM = i + 1;
  \   00000036   0x1C61             ADDS     R1,R4,#+1
  \                     ??TBug_3:
  \   00000038   0x7001             STRB     R1,[R0, #+0]
    54                return;
  \   0000003A   0xBCF0             POP      {R4-R7}
  \   0000003C   0x4770             BX       LR
    55              case 11:
    56                shiftState = SHIFT_STATE_REPORT;
  \                     ??TBug_5:
  \   0000003E   0x2604             MOVS     R6,#+4
  \   00000040   0x7046             STRB     R6,[R0, #+1]
    57          //      PingWatch();
    58              case 3:
    59                shadowRTC += secAdd;
  \                     ??TBug_6:
  \   00000042   0x6886             LDR      R6,[R0, #+8]
  \   00000044   0xF990 0x7002      LDRSB    R7,[R0, #+2]
  \   00000048   0x19BE             ADDS     R6,R7,R6
  \   0000004A   0x6086             STR      R6,[R0, #+8]
    60                if (stateTIM = i >>= 3) break;
  \   0000004C   0x08E4             LSRS     R4,R4,#+3
  \   0000004E   0x7004             STRB     R4,[R0, #+0]
  \   00000050   0x7806             LDRB     R6,[R0, #+0]
  \   00000052   0x2E00             CMP      R6,#+0
  \   00000054   0xD132             BNE.N    ??TBug_1
    61              case 0:
    62                if (shiftPoint == shadowRTC + 1 && shiftState == SHIFT_STATE_REQ) {
  \                     ??TBug_7:
  \   00000056   0x68C6             LDR      R6,[R0, #+12]
  \   00000058   0x6887             LDR      R7,[R0, #+8]
  \   0000005A   0x1C7F             ADDS     R7,R7,#+1
  \   0000005C   0x42BE             CMP      R6,R7
  \   0000005E   0xBF04             ITT      EQ 
  \   00000060   0x7846             LDRBEQ   R6,[R0, #+1]
  \   00000062   0x2E02             CMPEQ    R6,#+2
  \   00000064   0xD106             BNE.N    ??TBug_8
    63                  shiftState = SHIFT_STATE_ACT;
  \   00000066   0x2203             MOVS     R2,#+3
  \   00000068   0x7042             STRB     R2,[R0, #+1]
    64                  c = shiftMs;
  \   0000006A   0x6942             LDR      R2,[R0, #+20]
    65                  cc = shiftSec;
  \   0000006C   0xF990 0x5006      LDRSB    R5,[R0, #+6]
    66                  i = 10;
  \   00000070   0x240A             MOVS     R4,#+10
  \   00000072   0xE009             B.N      ??TBug_9
    67                }
    68              case 1:
    69                if (i < 2) {
  \                     ??TBug_8:
  \   00000074   0x2C02             CMP      R4,#+2
  \   00000076   0xD207             BCS.N    ??TBug_9
    70                  stateTIM = 0;
  \   00000078   0x2200             MOVS     R2,#+0
  \   0000007A   0x7002             STRB     R2,[R0, #+0]
    71                  if (adjTim & (1 << T_ADJ - 1) - 1) {
  \   0000007C   0x8882             LDRH     R2,[R0, #+4]
  \   0000007E   0x0454             LSLS     R4,R2,#+17
  \   00000080   0xD01C             BEQ.N    ??TBug_1
    72                    c = adjTim;
    73                    adjTim = cc = 0;
  \   00000082   0x2500             MOVS     R5,#+0
  \   00000084   0x8085             STRH     R5,[R0, #+4]
    74                    i = 2;
  \   00000086   0x2402             MOVS     R4,#+2
    75                  } else break;
    76                }
    77                secAdd = cc;
  \                     ??TBug_9:
  \   00000088   0x7085             STRB     R5,[R0, #+2]
    78                if ((u32)c < WATCH_BASE_CLK / 10) {
  \   0000008A   0x....             LDR.N    R5,??DataTable1_4  ;; 0x186a0
  \   0000008C   0x42AA             CMP      R2,R5
  \   0000008E   0xD208             BCS.N    ??TBug_10
    79                  if ((c += p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
  \   00000090   0x69CD             LDR      R5,[R1, #+28]
  \   00000092   0x18AA             ADDS     R2,R5,R2
  \   00000094   0x....             LDR.N    R5,??DataTable1_2  ;; 0xfff85ee0
  \   00000096   0x18AA             ADDS     R2,R5,R2
  \   00000098   0xBF44             ITT      MI 
  \   0000009A   0x....             LDRMI.N  R5,??DataTable1_3  ;; 0xf4240
  \   0000009C   0x18AA             ADDMI    R2,R5,R2
    80                  p->MR[1] = c;
  \   0000009E   0x61CA             STR      R2,[R1, #+28]
  \   000000A0   0xE00B             B.N      ??TBug_11
    81                } else {
    82                  if (c >= 0) i += 1;
  \                     ??TBug_10:
  \   000000A2   0x1C64             ADDS     R4,R4,#+1
    83                  if ((c += p->MR[1]) < 0) c += WATCH_BASE_CLK;
  \   000000A4   0x69CD             LDR      R5,[R1, #+28]
  \   000000A6   0x18AA             ADDS     R2,R5,R2
  \   000000A8   0x....             LDR.N    R5,??DataTable1_3  ;; 0xf4240
  \   000000AA   0xBF48             IT       MI 
  \   000000AC   0x18AA             ADDMI    R2,R5,R2
    84                  if (c >= WATCH_BASE_CLK) c -= WATCH_BASE_CLK;
  \   000000AE   0x42AA             CMP      R2,R5
  \   000000B0   0xBFA4             ITT      GE 
  \   000000B2   0x....             LDRGE.N  R5,??DataTable1_5  ;; 0xfff0bdc0
  \   000000B4   0x18AA             ADDGE    R2,R5,R2
    85                  p->MR[1] = c;
  \   000000B6   0x61CA             STR      R2,[R1, #+28]
    86                  i += 1;
  \   000000B8   0x1C64             ADDS     R4,R4,#+1
    87                }
    88                stateTIM = i;
  \                     ??TBug_11:
  \   000000BA   0x7004             STRB     R4,[R0, #+0]
    89            }
    90            pointTIM = j;
  \                     ??TBug_1:
  \   000000BC   0x6103             STR      R3,[R0, #+16]
    91            shadowRTC++;
  \   000000BE   0x6881             LDR      R1,[R0, #+8]
  \   000000C0   0x1C49             ADDS     R1,R1,#+1
  \   000000C2   0x6081             STR      R1,[R0, #+8]
    92          ///  PostEventRTC();
    93          }
  \   000000C4   0xBCF0             POP      {R4-R7}
  \   000000C6   0x4770             BX       LR               ;; return

  \                                 In section .bss, align 4
  \                     stateTIM:
  \   00000000                      DS8 1
  \                     shiftState:
  \   00000001                      DS8 1
  \   00000002                      DS8 1
  \   00000003                      DS8 1
  \                     adjTim:
  \   00000004                      DS8 2
  \                     shiftSec:
  \   00000006                      DS8 1
  \   00000007                      DS8 1
  \                     shadowRTC:
  \   00000008                      DS8 4
  \                     shiftPoint:
  \   0000000C                      DS8 4
  \                     pointTIM:
  \   00000010                      DS8 4
  \                     shiftMs:
  \   00000014                      DS8 4
    94          

  \                                 In section .text, align 2, keep-with-next
    95          int main() {}
  \                     main:
  \   00000000   0x2000             MOVS     R0,#+0
  \   00000002   0x4770             BX       LR               ;; return

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1:
  \   00000000   0x........         DC32     TIMER_0

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1_1:
  \   00000000   0x........         DC32     stateTIM

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1_2:
  \   00000000   0xFFF85EE0         DC32     0xfff85ee0

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1_3:
  \   00000000   0x000F4240         DC32     0xf4240

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1_4:
  \   00000000   0x000186A0         DC32     0x186a0

  \                                 In section .text, align 4, keep-with-next
  \                     ??DataTable1_5:
  \   00000000   0xFFF0BDC0         DC32     0xfff0bdc0

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


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

Нет сил анализировать этот шедевр, так что наличие бага не могу ни подтвердить, ни опровергнуть.

Если что, вот что нагенерил компилятор у меня:

Спасибо :)

У Вас баг также наличествует:

    82                  if (c >= 0) i += 1;
   \                     ??TBug_10:
   \   000000A2   0x1C64             ADDS     R4,R4,#+1

То же самое безусловное выполнение :(((

Хотя пришла мысль - пожалуй надо будет глянуть раздел настроек проекта касательно MISRA-C.....

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

 

Это не шедевр, это всего лишь часть кода отвечающая за подстройку частоты внутреннего таймера тактируемого от PLL LPC1788, под частоту внешних импульсов от внешнего RTC.

Подстройка методом ФАПЧ. :)

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


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

s32 c;  //signed int
if ((u32)c < 100000) {   //проверка как unsigned int. 
  ...
} else {                         // выполняем если с БОЛЬШЕ 99999. 
  if (c >= 0) i += 1;        // какой смысл еще раз проверять 
  i += 1;
}

 

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


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

Как раз специально для Вас я написал комменты ;)

Обратите внимание на s32 c; и на (u32)c и подумайте.

Там три ветви условного выполнения.

 

PS: Вобщем - это явный баг оптимизатора. Причём новый, появившийся с версии 6 IAR (в версии 5.50 всё было ок) :(((((((

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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