We find that the TMS320C55xx compiler is generating code that can fail with larger switch tables in use. XAR3 holds an address from the .switch section for a few instructions violating the rule for preservation of the upper 16bit of XAR registers (same as that of .bss) in the presense of interrupts. We suggest that either the documentation change to indicate that the .switch section should be located along with other data sections in the same page as .bss or the compiler should be changed to avoid this.
Here are the relevant sections from the documentation:
SPRU281F - TMS320C55x Optimizing C/C++ Compiler v 4.4
6.1.1 Small Memory Model
The use of the small memory model results in code and data sizes that are slightly smaller and more
efficient than when using the larger memory models. However, your program must meet certain size and
memory placement restrictions.
In the small memory model, the following sections must all fit within a single page of memory that is 64K
words in size.
• The .bss and .data sections (all static and global data)
• The .stack and .sysstack sections (the primary and secondary system stacks)
• The .sysmem section (dynamic memory space)
• The .const section
No section may cross a hardware page boundary. There is no other restriction on the size or placement of
.text sections (code), .switch sections (switch statements), or .cinit/.pinit sections (variable initialization).
In the small model, the compiler uses 16-bit data pointers to access data. The upper 7 bits of the XARn
registers are set to point to the page that contains the .bss section. They remain set to that value
throughout program execution.
SPRU376A TMS320C55x DSP Programmer’s Guide
3.5.4 Allocating Code and Data in the C55x Memory Map
“When compiling with the small memory model (compiler default) allocate all
data sections, .data, .bss, .stack, .sysmem, .sysstack, .cio, and .const, on the
first 64K word page of memory (Page 0).”
Our situation was as follows:
If the .switch section is placed outside of the page containing .bss it can cause corruption when a small model interrupt occurs. The data here has been setup for page 0 (first 64K words). But the .switch section was allowed to be in higher memory. This was following the above information (although the switch information is classified as data by the linker map). Note that the upper 16bits of the address are 1 here:
.switch 0 [ 0003d138 ] 0001e89c * 00000456
[ 0003d138 ] 0001e89c * 00000104 c_tim_gateway_aux.obj (.switch:_HandleAuxIndCtlMail__14CTimGatewayAuxFUiN21)
[ 0003d340 ] 0001e9a0 * 000000d8 aux_interface.obj (.switch:_auxHandleSetIndCtlMessages)
[ 0003d4f0 ] 0001ea78 * 00000054 c_dect_link_controller.obj (.switch:_Process__19CDectLinkControllerFP8CMessageUl)
If this code from a small model switch statement the target jump address is loaded using the switch table for the method (c_dect_link_controller). ACO gets the address of the jump location from the .switch data, but XAR3 upper 16 bits are contaminated to 0x1 by this. An interrupt happening just at the point of loading XAR3 results in a system crash in our builds. Either small model builds should generate switch table code that does not contaminate XAR3 or the documentation should indicate that .switch sections should be located in the same page as the other data along with .bss.
04092f: $C$DW$L$_Process__19CDectLinkControllerFP8CMessageUl$62$B:
04092f: 7c00019b SUB #1,AR3,AR1
040933: 7a00010a MOV #1 << #16,AC0
040937: 7eeab800_5190 OR #60088,AC0,AC0 || SFTL AR1,#1
04093d: 7dffff19 AND #65535,AR1,AC1
040941: 2410 ADD AC1,AC0
040943: 900b MOV AC0,XAR3
040945: ed6108 MOV dbl(*AR3),AC0
040948: ec31be004f7c AMAR *(#04f7ch),XAR3
04094e: 9100 B AC0
Below you can see the location where XAR3 has violated the rule.
