AnsweredAssumed Answered

Byte address becomes corrupted in simple loop

Question asked by Willi Hoffmann on Nov 6, 2014
Latest reply on Nov 12, 2014 by Fiona Kuang

Installed Products:

- CodeWarrior for MCU

     Version: 10.6

     Build Id:140329

 

I have the following Code for MC56F84769 which has a DSP56800E. It is just calculating a sum of all bytes over some range in P-Flash:

 

*****************************************************************************************************************************

UINT8 srvc_calc_pmem_byte_checksum_u8(UINT8 const __pmem *byte_addr_begin_pu8, UINT8 const __pmem *byte_addr_end_pu8)

{

  UINT8 const __pmem *p;

  UINT8 sum_u8 = 0;

 

  for(p = byte_addr_begin_pu8; p <= byte_addr_end_pu8; ++p)

  {

    sum_u8 += *p;

  }

 

  return sum_u8;

}

*******************************************************************************************************************************

 

 

I'm using large data model to compile. The Compiler does the following out of it:

*****************************************************************************************************************************

;

;  635:  */

;  636: UINT8 srvc_calc_pmem_byte_checksum_u8(UINT8 const __pmem *byte_addr_begin_pu8, UINT8 const __pmem *byte_addr_end_pu8)

;  637: {

;  638:   UINT8 const __pmem *p;

;  639:   UINT8 sum_u8 = 0;

;  640:    

;  641:     for(p = byte_addr_begin_pu8;

;

0x00000000              Fsrvc_calc_pmem_byte_checksum_u8:

0x00000000  0xE580                 move.w      #0,Y0

0x00000001  0xA90D                 bra         *+14

;

;  643:     sum_u8 += *p;

;  644:       }

;  645:      

;  646:       return sum_u8;

;

0x00000002  0x880A                 moveu.w     R2,R0

0x00000003  0x8D4A0001             bftsth      #1,R2

0x00000005  0x8536                 lsra        R2

0x00000006  0x836A                 move.w      P:(R2)+,A1

0x00000007  0xA003                 bcc         *+4

0x00000008  0xE700                 nop       

0x00000009  0xE700                 nop       

0x0000000A  0x5C68                 asrr.w      #0x000008,A

0x0000000B  0x7C02                 zxt.b       A,A

0x0000000C  0x8A08                 moveu.w     R0,R2

0x0000000D  0x7A80                 add         A,Y0

;

;  641:                                                        ++p)

;  642:                                                          {

;

0x0000000E  0x8172                 adda        #0x000001,R2

;

;  641:                                p <= byte_addr_end_pu8;

;

0x0000000F  0x8F33                 cmpa        R2,R3

0x00000010  0xA071                 bcc         *-14

0x00000011  0xE700                 nop       

;

;  647: }

;

0x00000012  0xE700                 nop       

0x00000013  0xE708                 rts       

 

*******************************************************************************************************************************************

 

 

You can see that at some point the Compiler uses "moveu.w R2,R0" to save R2 for later use. Because R2 holds the current address (R3 holds the end address). But R2 holds a byte address. If the byte address becomes 0x1E000 (which would be a word address 0xF000), I will lose the highest nibble of R2 because of the moveu.w instruction. Later when R0 is written back to R2, it makes R2 jump to 0xE000.

 

So am I doing anything wrong here? I am using large data model.

Outcomes