Есть такой код:
CODE
#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;
}
#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, другую не пробовал) превращается в такое:
CODE
\ 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 }
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 свои), чтобы не путались