Lv Zheng
2012-02-28 03:16:37 UTC
Hi, all
I'm new to this mailing list to report an old version avr-gcc bug which
might be a known bug and wonder if someone here can kindly give me hints if
there are any solutions.
We found this bug when we compile our project (sdfirm.sourceforge.net) using
avr-gcc-4.5.2 or avr-gcc-3.4.4.
C source codes are attached hereafter:
==================================================
#define MAKEWORD(a, b) ((uint16_t)(((uint16_t)(a)) | \
((uint16_t)(b)) << 8))
#define PN53X_LEN 3
#define PN53X_LCS 4
#define PN53X_TFI 5
#define PN53X_CMD 6
#define PN53X_PD(n) (PN53X_CMD+(n))
/* XXX: Workaround for an AVR-GCC Bug
* This function should be put into a seperate file to avoid a GCC bug when
* optimizations are performed on uint16_t operations for 8-bit AVR chips.
*/
boolean pn53x_is_ciu_register(uint16_t reg)
{
return (reg >= PN53X_REG_CIU_BASE) &&
(reg < (PN53X_REG_CIU_BASE + PN53X_REG_CIU_SIZE));
}
void pn53x_response_ReadRegister(void)
{
uint8_t i, j;
uint16_t reg;
uint8_t val;
for (i = 0, j = 0;
i < (pn53x_stub_cmd[PN53X_LEN]-2);
i += 2, j++) {
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
if (reg == PN53X_REG_Control_switch_rng) {
val = pn53x_ctrl_reg_switch_rng;
} else {
pn53x_response_error(PN53X_ERR_CMD);
return;
}
} else {
uint8_t mask;
uint8_t index = PN53X_CIU_REG2INDEX(reg);
mask = pn53x_ciu_readables[index];
val = (pn53x_ciu_read_register(reg) & mask);
}
pn53x_stub_resp[PN53X_PD(1)+j] = val;
}
pn53x_build_frame(j+2);
}
==================================================
The bug is occurred between the following codes:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are incorrect:
00004e60 <pn53x_response_ReadRegister>:
4e60: ef 92 push r14
4e62: ff 92 push r15
4e64: 0f 93 push r16
4e66: 1f 93 push r17
4e68: cf 93 push r28
4e6a: df 93 push r29
-----
4e6c: 10 e0 ldi r17, 0x00 ; 0
4e6e: 26 c0 rjmp .+76 ; 0x4ebc
<pn53x_response_ReadRegister+0x5c>
-----
loop:
j is assigned to r17
-----
4e70: fa 01 movw r30, r20
4e72: e5 53 subi r30, 0x35 ; 53
4e74: f7 4f sbci r31, 0xF7 ; 247
4e76: 80 e0 ldi r24, 0x00 ; 0
4e78: ec 01 movw r28, r24
4e7a: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(2)+i]
but we couldn't find any codes related to the pn53x_stub_cmd[PN53X_PD(1)+i]
hereafter...
-----
4e7c: 90 e0 ldi r25, 0x00 ; 0
4e7e: 8c 2b or r24, r28
4e80: 9d 2b or r25, r29
4e82: 9c 01 movw r18, r24
4e84: 20 50 subi r18, 0x00 ; 0
4e86: 33 46 sbci r19, 0x63 ; 99
4e88: 20 34 cpi r18, 0x40 ; 64
4e8a: 31 05 cpc r19, r1
4e8c: 50 f0 brcs .+20 ; 0x4ea2
<pn53x_response_ReadRegister+0x42>
4e8e: 21 e6 ldi r18, 0x61 ; 97
4e90: 86 30 cpi r24, 0x06 ; 6
4e92: 92 07 cpc r25, r18
4e94: 19 f4 brne .+6 ; 0x4e9c
<pn53x_response_ReadRegister+0x3c>
4e96: 80 91 a0 06 lds r24, 0x06A0
4e9a: 0a c0 rjmp .+20 ; 0x4eb0
<pn53x_response_ReadRegister+0x50>
4e9c: 87 e2 ldi r24, 0x27 ; 39
4e9e: 16 df rcall .-468 ; 0x4ccc <pn53x_response_error>
4ea0: 1b c0 rjmp .+54 ; 0x4ed8
<pn53x_response_ReadRegister+0x78>
4ea2: e8 2f mov r30, r24
4ea4: f0 e0 ldi r31, 0x00 ; 0
4ea6: ec 53 subi r30, 0x3C ; 60
4ea8: fd 4f sbci r31, 0xFD ; 253
4eaa: 00 81 ld r16, Z
4eac: c5 df rcall .-118 ; 0x4e38 <pn53x_ciu_read_register>
4eae: 80 23 and r24, r16
4eb0: e1 2f mov r30, r17
4eb2: f0 e0 ldi r31, 0x00 ; 0
4eb4: ea 56 subi r30, 0x6A ; 106
4eb6: f8 4f sbci r31, 0xF8 ; 248
4eb8: 87 83 std Z+7, r24 ; 0x07
4eba: 1f 5f subi r17, 0xFF ; 255
-----
4ebc: 41 2f mov r20, r17
4ebe: 44 0f add r20, r20
4ec0: 50 e0 ldi r21, 0x00 ; 0
4ec2: 20 91 ce 08 lds r18, 0x08CE
4ec6: 30 e0 ldi r19, 0x00 ; 0
4ec8: 22 50 subi r18, 0x02 ; 2
4eca: 30 40 sbci r19, 0x00 ; 0
4ecc: 42 17 cp r20, r18
4ece: 53 07 cpc r21, r19
4ed0: 7c f2 brlt .-98 ; 0x4e70
<pn53x_response_ReadRegister+0x10>
-----
loop:
i is assigned to r20
pn53x_stub_cmd[PN53X_LEN]-2 is assigned to r18,r19
-----
4ed2: 81 2f mov r24, r17
4ed4: 8e 5f subi r24, 0xFE ; 254
4ed6: d2 de rcall .-604 ; 0x4c7c <pn53x_build_frame>
4ed8: df 91 pop r29
4eda: cf 91 pop r28
4edc: 1f 91 pop r17
4ede: 0f 91 pop r16
4ee0: ff 90 pop r15
4ee2: ef 90 pop r14
4ee4: 08 95 ret
==================================================
Assembly generations are vary if we put a simple uart print code between the
two lines as:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
uart_putchar(0x00);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are correct:
00002a5a <pn53x_response_ReadRegister>:
2a5a: ef 92 push r14
2a5c: ff 92 push r15
2a5e: 0f 93 push r16
2a60: 1f 93 push r17
2a62: cf 93 push r28
2a64: df 93 push r29
2a66: ff 24 eor r15, r15
2a68: 2a c0 rjmp .+84 ; 0x2abe
<pn53x_response_ReadRegister+0x64>
-----
2a6a: fa 01 movw r30, r20
2a6c: e0 57 subi r30, 0x70 ; 112
2a6e: f7 4f sbci r31, 0xF7 ; 247
2a70: 17 81 ldd r17, Z+7 ; 0x07
2a72: 00 e0 ldi r16, 0x00 ; 0
-----
now r16,r17 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a74: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a76: c8 2f mov r28, r24
2a78: d0 e0 ldi r29, 0x00 ; 0
2a7a: c0 2b or r28, r16
2a7c: d1 2b or r29, r17
-----
now r28,r29 containe the MAKEWORD result
-----
2a7e: 80 e0 ldi r24, 0x00 ; 0
2a80: 24 d4 rcall .+2120 ; 0x32ca <uart_hw_write_byte>
2a82: ce 01 movw r24, r28
2a84: 80 50 subi r24, 0x00 ; 0
2a86: 93 46 sbci r25, 0x63 ; 99
2a88: 80 34 cpi r24, 0x40 ; 64
2a8a: 91 05 cpc r25, r1
2a8c: 50 f0 brcs .+20 ; 0x2aa2
<pn53x_response_ReadRegister+0x48>
2a8e: 81 e6 ldi r24, 0x61 ; 97
2a90: c6 30 cpi r28, 0x06 ; 6
2a92: d8 07 cpc r29, r24
2a94: 19 f4 brne .+6 ; 0x2a9c
<pn53x_response_ReadRegister+0x42>
2a96: 80 91 c4 04 lds r24, 0x04C4
2a9a: 0b c0 rjmp .+22 ; 0x2ab2
<pn53x_response_ReadRegister+0x58>
2a9c: 87 e2 ldi r24, 0x27 ; 39
2a9e: 16 df rcall .-468 ; 0x28cc <pn53x_response_error>
2aa0: 1c c0 rjmp .+56 ; 0x2ada
<pn53x_response_ReadRegister+0x80>
2aa2: ce 01 movw r24, r28
2aa4: ec 2f mov r30, r28
2aa6: f0 e0 ldi r31, 0x00 ; 0
2aa8: e5 50 subi r30, 0x05 ; 5
2aaa: fe 4f sbci r31, 0xFE ; 254
2aac: e0 80 ld r14, Z
2aae: c2 df rcall .-124 ; 0x2a34 <pn53x_ciu_read_register>
2ab0: 8e 21 and r24, r14
2ab2: ef 2d mov r30, r15
2ab4: f0 e0 ldi r31, 0x00 ; 0
2ab6: e5 5a subi r30, 0xA5 ; 165
2ab8: f8 4f sbci r31, 0xF8 ; 248
2aba: 87 83 std Z+7, r24 ; 0x07
2abc: f3 94 inc r15
2abe: 4f 2d mov r20, r15
2ac0: 44 0f add r20, r20
2ac2: 50 e0 ldi r21, 0x00 ; 0
2ac4: 20 91 93 08 lds r18, 0x0893
2ac8: 30 e0 ldi r19, 0x00 ; 0
2aca: 22 50 subi r18, 0x02 ; 2
2acc: 30 40 sbci r19, 0x00 ; 0
2ace: 42 17 cp r20, r18
2ad0: 53 07 cpc r21, r19
2ad2: 5c f2 brlt .-106 ; 0x2a6a
<pn53x_response_ReadRegister+0x10>
2ad4: 8f 2d mov r24, r15
2ad6: 8e 5f subi r24, 0xFE ; 254
2ad8: d1 de rcall .-606 ; 0x287c <pn53x_build_frame>
2ada: df 91 pop r29
2adc: cf 91 pop r28
2ade: 1f 91 pop r17
2ae0: 0f 91 pop r16
2ae2: ff 90 pop r15
2ae4: ef 90 pop r14
2ae6: 08 95 ret
==================================================
The cc command line is listed as the following:
avr-gcc -Wp,-MD,drivers/scs/.pn53x_stub.rel.d
-nostdinc -nostdlib -D__KERNEL__ -Iinclude
-Wall -DKBUILD_CONF -Iinclude
-D__AVR__
-ffunction-sections -fsigned-char -mmcu=avr51
-D__AVR_ENHANCED__ -D__AVR_MEGA__ -D__AVR_2_BYTE_PC__
-Os -fomit-frame-pointer
-o drivers/scs/pn53x_stub.rel -c drivers/scs/pn53x_stub.c
Best regards/Lv ZETALOG Zheng
I'm new to this mailing list to report an old version avr-gcc bug which
might be a known bug and wonder if someone here can kindly give me hints if
there are any solutions.
We found this bug when we compile our project (sdfirm.sourceforge.net) using
avr-gcc-4.5.2 or avr-gcc-3.4.4.
C source codes are attached hereafter:
==================================================
#define MAKEWORD(a, b) ((uint16_t)(((uint16_t)(a)) | \
((uint16_t)(b)) << 8))
#define PN53X_LEN 3
#define PN53X_LCS 4
#define PN53X_TFI 5
#define PN53X_CMD 6
#define PN53X_PD(n) (PN53X_CMD+(n))
/* XXX: Workaround for an AVR-GCC Bug
* This function should be put into a seperate file to avoid a GCC bug when
* optimizations are performed on uint16_t operations for 8-bit AVR chips.
*/
boolean pn53x_is_ciu_register(uint16_t reg)
{
return (reg >= PN53X_REG_CIU_BASE) &&
(reg < (PN53X_REG_CIU_BASE + PN53X_REG_CIU_SIZE));
}
void pn53x_response_ReadRegister(void)
{
uint8_t i, j;
uint16_t reg;
uint8_t val;
for (i = 0, j = 0;
i < (pn53x_stub_cmd[PN53X_LEN]-2);
i += 2, j++) {
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
if (reg == PN53X_REG_Control_switch_rng) {
val = pn53x_ctrl_reg_switch_rng;
} else {
pn53x_response_error(PN53X_ERR_CMD);
return;
}
} else {
uint8_t mask;
uint8_t index = PN53X_CIU_REG2INDEX(reg);
mask = pn53x_ciu_readables[index];
val = (pn53x_ciu_read_register(reg) & mask);
}
pn53x_stub_resp[PN53X_PD(1)+j] = val;
}
pn53x_build_frame(j+2);
}
==================================================
The bug is occurred between the following codes:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are incorrect:
00004e60 <pn53x_response_ReadRegister>:
4e60: ef 92 push r14
4e62: ff 92 push r15
4e64: 0f 93 push r16
4e66: 1f 93 push r17
4e68: cf 93 push r28
4e6a: df 93 push r29
-----
4e6c: 10 e0 ldi r17, 0x00 ; 0
4e6e: 26 c0 rjmp .+76 ; 0x4ebc
<pn53x_response_ReadRegister+0x5c>
-----
loop:
j is assigned to r17
-----
4e70: fa 01 movw r30, r20
4e72: e5 53 subi r30, 0x35 ; 53
4e74: f7 4f sbci r31, 0xF7 ; 247
4e76: 80 e0 ldi r24, 0x00 ; 0
4e78: ec 01 movw r28, r24
4e7a: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(2)+i]
but we couldn't find any codes related to the pn53x_stub_cmd[PN53X_PD(1)+i]
hereafter...
-----
4e7c: 90 e0 ldi r25, 0x00 ; 0
4e7e: 8c 2b or r24, r28
4e80: 9d 2b or r25, r29
4e82: 9c 01 movw r18, r24
4e84: 20 50 subi r18, 0x00 ; 0
4e86: 33 46 sbci r19, 0x63 ; 99
4e88: 20 34 cpi r18, 0x40 ; 64
4e8a: 31 05 cpc r19, r1
4e8c: 50 f0 brcs .+20 ; 0x4ea2
<pn53x_response_ReadRegister+0x42>
4e8e: 21 e6 ldi r18, 0x61 ; 97
4e90: 86 30 cpi r24, 0x06 ; 6
4e92: 92 07 cpc r25, r18
4e94: 19 f4 brne .+6 ; 0x4e9c
<pn53x_response_ReadRegister+0x3c>
4e96: 80 91 a0 06 lds r24, 0x06A0
4e9a: 0a c0 rjmp .+20 ; 0x4eb0
<pn53x_response_ReadRegister+0x50>
4e9c: 87 e2 ldi r24, 0x27 ; 39
4e9e: 16 df rcall .-468 ; 0x4ccc <pn53x_response_error>
4ea0: 1b c0 rjmp .+54 ; 0x4ed8
<pn53x_response_ReadRegister+0x78>
4ea2: e8 2f mov r30, r24
4ea4: f0 e0 ldi r31, 0x00 ; 0
4ea6: ec 53 subi r30, 0x3C ; 60
4ea8: fd 4f sbci r31, 0xFD ; 253
4eaa: 00 81 ld r16, Z
4eac: c5 df rcall .-118 ; 0x4e38 <pn53x_ciu_read_register>
4eae: 80 23 and r24, r16
4eb0: e1 2f mov r30, r17
4eb2: f0 e0 ldi r31, 0x00 ; 0
4eb4: ea 56 subi r30, 0x6A ; 106
4eb6: f8 4f sbci r31, 0xF8 ; 248
4eb8: 87 83 std Z+7, r24 ; 0x07
4eba: 1f 5f subi r17, 0xFF ; 255
-----
4ebc: 41 2f mov r20, r17
4ebe: 44 0f add r20, r20
4ec0: 50 e0 ldi r21, 0x00 ; 0
4ec2: 20 91 ce 08 lds r18, 0x08CE
4ec6: 30 e0 ldi r19, 0x00 ; 0
4ec8: 22 50 subi r18, 0x02 ; 2
4eca: 30 40 sbci r19, 0x00 ; 0
4ecc: 42 17 cp r20, r18
4ece: 53 07 cpc r21, r19
4ed0: 7c f2 brlt .-98 ; 0x4e70
<pn53x_response_ReadRegister+0x10>
-----
loop:
i is assigned to r20
pn53x_stub_cmd[PN53X_LEN]-2 is assigned to r18,r19
-----
4ed2: 81 2f mov r24, r17
4ed4: 8e 5f subi r24, 0xFE ; 254
4ed6: d2 de rcall .-604 ; 0x4c7c <pn53x_build_frame>
4ed8: df 91 pop r29
4eda: cf 91 pop r28
4edc: 1f 91 pop r17
4ede: 0f 91 pop r16
4ee0: ff 90 pop r15
4ee2: ef 90 pop r14
4ee4: 08 95 ret
==================================================
Assembly generations are vary if we put a simple uart print code between the
two lines as:
==================================================
reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i],
pn53x_stub_cmd[PN53X_PD(1)+i]);
uart_putchar(0x00);
if (!pn53x_is_ciu_register(reg)) {
==================================================
Assembly generations are correct:
00002a5a <pn53x_response_ReadRegister>:
2a5a: ef 92 push r14
2a5c: ff 92 push r15
2a5e: 0f 93 push r16
2a60: 1f 93 push r17
2a62: cf 93 push r28
2a64: df 93 push r29
2a66: ff 24 eor r15, r15
2a68: 2a c0 rjmp .+84 ; 0x2abe
<pn53x_response_ReadRegister+0x64>
-----
2a6a: fa 01 movw r30, r20
2a6c: e0 57 subi r30, 0x70 ; 112
2a6e: f7 4f sbci r31, 0xF7 ; 247
2a70: 17 81 ldd r17, Z+7 ; 0x07
2a72: 00 e0 ldi r16, 0x00 ; 0
-----
now r16,r17 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a74: 80 85 ldd r24, Z+8 ; 0x08
-----
now r24 is pn53x_stub_cmd[PN53X_PD(1)+i]
-----
2a76: c8 2f mov r28, r24
2a78: d0 e0 ldi r29, 0x00 ; 0
2a7a: c0 2b or r28, r16
2a7c: d1 2b or r29, r17
-----
now r28,r29 containe the MAKEWORD result
-----
2a7e: 80 e0 ldi r24, 0x00 ; 0
2a80: 24 d4 rcall .+2120 ; 0x32ca <uart_hw_write_byte>
2a82: ce 01 movw r24, r28
2a84: 80 50 subi r24, 0x00 ; 0
2a86: 93 46 sbci r25, 0x63 ; 99
2a88: 80 34 cpi r24, 0x40 ; 64
2a8a: 91 05 cpc r25, r1
2a8c: 50 f0 brcs .+20 ; 0x2aa2
<pn53x_response_ReadRegister+0x48>
2a8e: 81 e6 ldi r24, 0x61 ; 97
2a90: c6 30 cpi r28, 0x06 ; 6
2a92: d8 07 cpc r29, r24
2a94: 19 f4 brne .+6 ; 0x2a9c
<pn53x_response_ReadRegister+0x42>
2a96: 80 91 c4 04 lds r24, 0x04C4
2a9a: 0b c0 rjmp .+22 ; 0x2ab2
<pn53x_response_ReadRegister+0x58>
2a9c: 87 e2 ldi r24, 0x27 ; 39
2a9e: 16 df rcall .-468 ; 0x28cc <pn53x_response_error>
2aa0: 1c c0 rjmp .+56 ; 0x2ada
<pn53x_response_ReadRegister+0x80>
2aa2: ce 01 movw r24, r28
2aa4: ec 2f mov r30, r28
2aa6: f0 e0 ldi r31, 0x00 ; 0
2aa8: e5 50 subi r30, 0x05 ; 5
2aaa: fe 4f sbci r31, 0xFE ; 254
2aac: e0 80 ld r14, Z
2aae: c2 df rcall .-124 ; 0x2a34 <pn53x_ciu_read_register>
2ab0: 8e 21 and r24, r14
2ab2: ef 2d mov r30, r15
2ab4: f0 e0 ldi r31, 0x00 ; 0
2ab6: e5 5a subi r30, 0xA5 ; 165
2ab8: f8 4f sbci r31, 0xF8 ; 248
2aba: 87 83 std Z+7, r24 ; 0x07
2abc: f3 94 inc r15
2abe: 4f 2d mov r20, r15
2ac0: 44 0f add r20, r20
2ac2: 50 e0 ldi r21, 0x00 ; 0
2ac4: 20 91 93 08 lds r18, 0x0893
2ac8: 30 e0 ldi r19, 0x00 ; 0
2aca: 22 50 subi r18, 0x02 ; 2
2acc: 30 40 sbci r19, 0x00 ; 0
2ace: 42 17 cp r20, r18
2ad0: 53 07 cpc r21, r19
2ad2: 5c f2 brlt .-106 ; 0x2a6a
<pn53x_response_ReadRegister+0x10>
2ad4: 8f 2d mov r24, r15
2ad6: 8e 5f subi r24, 0xFE ; 254
2ad8: d1 de rcall .-606 ; 0x287c <pn53x_build_frame>
2ada: df 91 pop r29
2adc: cf 91 pop r28
2ade: 1f 91 pop r17
2ae0: 0f 91 pop r16
2ae2: ff 90 pop r15
2ae4: ef 90 pop r14
2ae6: 08 95 ret
==================================================
The cc command line is listed as the following:
avr-gcc -Wp,-MD,drivers/scs/.pn53x_stub.rel.d
-nostdinc -nostdlib -D__KERNEL__ -Iinclude
-Wall -DKBUILD_CONF -Iinclude
-D__AVR__
-ffunction-sections -fsigned-char -mmcu=avr51
-D__AVR_ENHANCED__ -D__AVR_MEGA__ -D__AVR_2_BYTE_PC__
-Os -fomit-frame-pointer
-o drivers/scs/pn53x_stub.rel -c drivers/scs/pn53x_stub.c
Best regards/Lv ZETALOG Zheng