jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Имеем (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 более новый - можете проверить - исправлено это или ещё нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Попробовал такой код: 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 (изменено) · Жалоба Да, Ваш и у меня правильно компилится. И если мою функцию урезать - тоже начинает правильно. Но в изначальном виде - баг! Приведу функцию в исходном виде (почти как у меня в рабочем варианте). Извините что так много, но при урезании функции начинает нормально компилить. %-\ #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 и определения типов. Изменено 20 августа, 2012 пользователем IgorKossak концевые табы!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Можете это попробовать скомпилить? Скопировал сюда вроде все необходимые define и определения типов. Попробовал - не компилится, причём по очевидным причинам. Если сделаете пример, который действительно можно вставить в пустой проект и скомпилировать, тогда попробую. Update: Да, и здесь принято длинные куски кода заворачивать в теги CODEBOX. Не напрягайте модераторов без необходимости - подкорректируйте сами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 89 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Куда делось условное исполнение: if (c >= 0) i += 1; ???? Компилятор посмотрел, что результат от этого кода нигде не используется и благополучно его выкинул. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Создал пустой проект, скомпилил, цепляю сюда аттачем. SRC.2.ZIP Компилятор посмотрел, что результат от этого кода нигде не используется и благополучно его выкинул. Во-первых: используется, смотрите внимательнее. Во-вторых: не выкинул, а сделал безусловным, смотрите внимательнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 89 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Во-первых: используется, смотрите внимательнее. Судя по этому коду ничего не видно т.к. не видно где используется i . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Видно: 561 stateTIM = i; \ ??TBug_11: \ 000000B8 0C70 STRB R4,[R1, #+0] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Семён Семёныч! У вас прямо перед сравнением переменная 'c' получает значение переменной adjTim, которая имеет тип u16. То есть при сравнении переменная 'c' заведомо неотрицательная. Не нужно писать такой жуткий код, тогда будете в нём меньше путаться. Я думаю, в такой программе вылезет ещё не один сюрприз. Не спешите винить компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Семён Семёныч! У вас прямо перед сравнением переменная 'c' получает значение переменной adjTim, которая имеет тип u16. То есть при сравнении переменная 'c' заведомо неотрицательная. Не нужно писать такой жуткий код, тогда будете в нём меньше путаться. Я думаю, в такой программе вылезет ещё не один сюрприз. Не спешите винить компилятор. Где заведомо? Вы что-то путаете ;) А Вы видите if (i < 2) немного выше и c = shiftMs; ? Да, кстати, Вы совершенно правы - при минимизации исходника и обрезки всего, перепутал тип adjTim. Он в оригинале: s16. Но это роли не играет. Так как значение c может быть присвоено ранее. Вобщем, по алгоритму, на входе в злополучное сравнение, переменная c может принимать любое значение из диапазона: -2^31...2^31-1. А насчёт жуткости - Вы видимо не видели по настоящему жутких исходников ;) Ближе к телу: Вы пробовали скомпилить это на Вашем компиляторе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Где заведомо? Вы что-то путаете ;) А Вы видите 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 20 августа, 2012 Опубликовано 20 августа, 2012 · Жалоба Нет сил анализировать этот шедевр, так что наличие бага не могу ни подтвердить, ни опровергнуть. Если что, вот что нагенерил компилятор у меня: Спасибо :) У Вас баг также наличествует: 82 if (c >= 0) i += 1; \ ??TBug_10: \ 000000A2 0x1C64 ADDS R4,R4,#+1 То же самое безусловное выполнение :((( Хотя пришла мысль - пожалуй надо будет глянуть раздел настроек проекта касательно MISRA-C..... У меня здесь везде используется арифметика с переполнением разрядной сетки, там вроде были какие-то ограничения оптимизатора насчёт этого. Это не шедевр, это всего лишь часть кода отвечающая за подстройку частоты внутреннего таймера тактируемого от PLL LPC1788, под частоту внешних импульсов от внешнего RTC. Подстройка методом ФАПЧ. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrey190 2 21 августа, 2012 Опубликовано 21 августа, 2012 · Жалоба s32 c; //signed int if ((u32)c < 100000) { //проверка как unsigned int. ... } else { // выполняем если с БОЛЬШЕ 99999. if (c >= 0) i += 1; // какой смысл еще раз проверять i += 1; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 21 августа, 2012 Опубликовано 21 августа, 2012 · Жалоба Как раз специально для Вас я написал комменты ;) Обратите внимание на s32 c; и на (u32)c и подумайте. Там три ветви условного выполнения. PS: Вобщем - это явный баг оптимизатора. Причём новый, появившийся с версии 6 IAR (в версии 5.50 всё было ок) :((((((( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 21 августа, 2012 Опубликовано 21 августа, 2012 · Жалоба Ну да, похоже на баг. Хорошо бы написать баг-репорт в Яр, чтобы пофиксили... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться