From: Anthony A. <ant...@gm...> - 2010-04-05 23:37:16
|
Hello SDCC-users, While working on the contiki OS, I found a strange behavior in SDCC. I noticed when a variable was cast as (void *) the generated code differed than if cast as (u8_t*). Here is the example demonstrating the issue: memset((*void **)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); vs memset((*u8_t **)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); 1600 ; ../../core/net/uip-nd6-io.c:344: memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); The problem/differences comes at 1610 when indexing into nd6_opt_llao to reach addr. In the (void *) version 0x02 is added, ignoring the addition of UIP_LLADDR_LEN. 05A9 90s00r01 1601 mov dptr,#_nd6_opt_llao 05AC E0 1602 movx a,@dptr 05AD FA 1603 mov r2,a 05AE A3 1604 inc dptr 05AF E0 1605 movx a,@dptr 05B0 FB 1606 mov r3,a 05B1 A3 1607 inc dptr 05B2 E0 1608 movx a,@dptr 05B3 FC 1609 mov r4,a 05B4 74 02 1610 mov a,#0x02 05B6 2A 1611 add a,r2 05B7 FA 1612 mov r2,a 05B8 E4 1613 clr a 05B9 3B 1614 addc a,r3 05BA FB 1615 mov r3,a 05BB 74 06 1616 mov a,#0x06 05BD C0 E0 1617 push acc 05BF E4 1618 clr a 05C0 C0 E0 1619 push acc 05C2 E4 1620 clr a 05C3 C0 E0 1621 push acc 05C5 8A 82 1622 mov dpl,r2 05C7 8B 83 1623 mov dph,r3 05C9 8C F0 1624 mov b,r4 05CB 12s00r00 1625 lcall _memset In the (u8_t *) version the correct offset for addr of 10 is used: 1600 ; ../../core/net/uip-nd6-io.c:344: memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); 05A9 90s00r01 1601 mov dptr,#_nd6_opt_llao 05AC E0 1602 movx a,@dptr 05AD FA 1603 mov r2,a 05AE A3 1604 inc dptr 05AF E0 1605 movx a,@dptr 05B0 FB 1606 mov r3,a 05B1 A3 1607 inc dptr 05B2 E0 1608 movx a,@dptr 05B3 FC 1609 mov r4,a 05B4 74 0A 1610 mov a,#0x0A 05B6 2A 1611 add a,r2 05B7 FA 1612 mov r2,a 05B8 E4 1613 clr a 05B9 3B 1614 addc a,r3 05BA FB 1615 mov r3,a 05BB 74 06 1616 mov a,#0x06 05BD C0 E0 1617 push acc 05BF E4 1618 clr a 05C0 C0 E0 1619 push acc 05C2 E4 1620 clr a 05C3 C0 E0 1621 push acc 05C5 8A 82 1622 mov dpl,r2 05C7 8B 83 1623 mov dph,r3 05C9 8C F0 1624 mov b,r4 05CB 12s00r00 1625 lcall _memset I submitted a bug tracker report with the following example program: #include <string.h> #define UIP_LLADDR_LEN 8 struct uip_802154_longaddr { unsigned char addr[8]; }; typedef struct uip_802154_longaddr uip_lladdr_t; struct uip_nd6_opt_llao { unsigned char type; unsigned char len; uip_lladdr_t addr; }; static struct uip_nd6_opt_llao *nd6_opt_llao; void main (void) { unsigned char buf[300]; nd6_opt_llao = (struct uip_nd6_opt_llao *)buf; memset((unsigned char *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, 6); } |