GCC's RISC-V -msmall-data-limit option - Page 1
Forum section: electronics / general

author: HwAoRrDk
author_rank: Super Contributor
timestamp: July 25, 2023, 11:57:53 pm
content: When compiling code for the WCH CH32V RISC-V series of microcontrollers, I see that some people use (including I believe the WCH MounRiver Studio default options) the GCC option-msmall-data-limit=8. The GCC documentation isn't particularly illuminating on the effect of this option. It just says:QuoteWhat is this 'special' section? Which targets does this apply to? Why would you want to put global/static data smaller than 8 bytes into a special section? What is the significance of the threshold of 8 bytes?

author: brucehoult
author_rank: Super Contributor
timestamp: July 26, 2023, 12:20:07 am
content: Global data is stored in memory with .sdata at lower addresses and .data following it.The GP register is initialized to 2048 bytes past the start of .sdata.Global variables from GP-2048 to GP+2047 can be accessed using just 1 instruction. If .sdata is smaller than 4K then all of .sdata can be accessed with a single instruction, and some of the start of .data too.

author: langwadt
author_rank: Super Contributor
timestamp: July 26, 2023, 12:30:18 am
content: I'm guessing the the special section is just an area of memory you keep a pointer to so you can save some code address it relative to that pointerI assume the 8 bytes is just a compromise of not using up the area you can easily address with large variables, where loading an address isn't much overhead compared to the variable itself

author: HwAoRrDk
author_rank: Super Contributor
timestamp: July 26, 2023, 12:38:21 am
content: Ah, so it's a code-size optimisation?If I'm understanding correctly, by giving this option with a size of 8 bytes, you're effectively saying try to put as many initialised uint64_t-or-smaller global/static variables into the .sdata section as possible, which means that they have priority of residence in lower addresses than other global/static variables.So if you have less than 4K of variables in .data full stop then this option will have no effect? I tried adding the option to a small project of mine that only uses 16 bytes in .data and it had no effect on the .text size. But then on something like the CH32V003 where there is only 2KB of RAM anyway, I suppose you'llneverhave any variables in .data outside the offset range from GP anyway.

author: brucehoult
author_rank: Super Contributor
timestamp: July 26, 2023, 01:08:29 am
content: Quote from: HwAoRrDk on July 26, 2023, 12:38:21 amNo *practical* effect. Some things may end up at different addresses.QuoteIndeed so, but WCH do use the same IDE for larger chips.Of course .bss is somewhere in that area too. I don't recall the exact ordering compared to .data. There is also .sbss.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: July 26, 2023, 08:28:16 pm
content: Quote from: brucehoult on July 26, 2023, 01:08:29 amThis is the section of the linker script (as provided by WCH) concerning .data and .bss:Code:.data :{. = ALIGN(4);*(.gnu.linkonce.r.*)*(.data .data.*)*(.gnu.linkonce.d.*). = ALIGN(8);PROVIDE( __global_pointer$ = . + 0x800 );*(.sdata .sdata.*)*(.sdata2*)*(.gnu.linkonce.s.*). = ALIGN(8);*(.srodata.cst16)*(.srodata.cst8)*(.srodata.cst4)*(.srodata.cst2)*(.srodata .srodata.*). = ALIGN(4);PROVIDE( _edata = .);} >RAM AT>FLASH.bss :{. = ALIGN(4);PROVIDE( _sbss = .);*(.sbss*)*(.gnu.linkonce.sb.*)*(.bss*)*(.gnu.linkonce.b.*)*(COMMON*). = ALIGN(4);PROVIDE( _ebss = .);} >RAM AT>FLASHIndeed there is also .sbss. But, am I missing something here, or does the script specify that .data comesbefore.sdata?I am not too familiar with GNU linker script syntax.

author: ejeffrey
author_rank: Super Contributor
timestamp: July 26, 2023, 09:06:36 pm
content: Yes, the order is something like:.data.sdata.sbss.bssso that sdata and sbss are adjacent and ideally both within range of gp. It also has a .srodata for small read-only data in there. I don't see a regular .rodata. I guess that probably is in flash and part of the linker script not shown.