cancel
Showing results for 
Search instead for 
Did you mean: 

Howto reserve global register variable gcc?

MM..1
Chief III

I try optimize to maximum MCU offload this operation:

I2S DMA stores sample LRLRLRLR... circular

i need reorder it to LLLLLLRRRRR in other memory place.

I mean DMA or other hw methods cant copy mem to mem with skip defined, mean every other.

Then i try write ISR and asm result is

08000c00 <SPI2_IRQHandler>:
  * @brief This function handles SPI2 global interrupt.
  */
void SPI2_IRQHandler(void)
{
  /* USER CODE BEGIN SPI2_IRQn 0 */
	*(int *)a = *(int *)b++;
 8000c00:	f859 3b01 	ldr.w	r3, [r9], #1
 8000c04:	f8c8 3000 	str.w	r3, [r8]
	*(int *)(a+256) = *(int *)b++;
 8000c08:	f859 3b01 	ldr.w	r3, [r9], #1
 8000c0c:	f8c8 3100 	str.w	r3, [r8, #256]	; 0x100
	a++;
 8000c10:	f108 0801 	add.w	r8, r8, #1
  /* USER CODE END SPI2_IRQn 0 */
//  HAL_I2S_IRQHandler(&hi2s2);
  /* USER CODE BEGIN SPI2_IRQn 1 */
 
  /* USER CODE END SPI2_IRQn 1 */
}
 8000c14:	4770      	bx	lr
 8000c16:	bf00      	nop

Registers r8 and r9 i declare in main.h as

register unsigned int a asm("r8");
register unsigned int b asm("r9");

Seems ISR is compiled good, but in all asm i found, that r8 and r9 is used on other places in many functions. Howto prevent this ???

3 REPLIES 3
MM..1
Chief III
08000c00 <SPI2_IRQHandler>:
  * @brief This function handles SPI2 global interrupt.
  */
void SPI2_IRQHandler(void)
{
  /* USER CODE BEGIN SPI2_IRQn 0 */
	*(int *)a = *(int *)b++;
 8000c00:	4b08      	ldr	r3, [pc, #32]	; (8000c24 <SPI2_IRQHandler+0x24>)
 8000c02:	4a09      	ldr	r2, [pc, #36]	; (8000c28 <SPI2_IRQHandler+0x28>)
 8000c04:	6819      	ldr	r1, [r3, #0]
 8000c06:	1c48      	adds	r0, r1, #1
 8000c08:	6018      	str	r0, [r3, #0]
 8000c0a:	6810      	ldr	r0, [r2, #0]
 8000c0c:	6809      	ldr	r1, [r1, #0]
 8000c0e:	6001      	str	r1, [r0, #0]
	*(int *)(a++ +256) = *(int *)b++;
 8000c10:	6819      	ldr	r1, [r3, #0]
 8000c12:	1c48      	adds	r0, r1, #1
 8000c14:	6018      	str	r0, [r3, #0]
 8000c16:	6813      	ldr	r3, [r2, #0]
 8000c18:	1c58      	adds	r0, r3, #1
 8000c1a:	6010      	str	r0, [r2, #0]
 8000c1c:	680a      	ldr	r2, [r1, #0]
 8000c1e:	f8c3 2100 	str.w	r2, [r3, #256]	; 0x100
  /* USER CODE END SPI2_IRQn 0 */
//  HAL_I2S_IRQHandler(&hi2s2);
  /* USER CODE BEGIN SPI2_IRQn 1 */
 
  /* USER CODE END SPI2_IRQn 1 */
}
 8000c22:	4770      	bx	lr
 8000c24:	20000288 	.word	0x20000288
 8000c28:	20000284 	.word	0x20000284

Nobody helps ? This is for compare normal variable build. As you can see register code use 5 instruction and normal code 16 when variables is __IO.

Without __IO build add 2 next instruction complete 18.

You know some of us have other jobs, and can't be chasing bizarre corner cases people paint themselves into. You might need to dig into the specifics of GNU GCC/GAS as it relates to the features you're trying to use, and the system level expectations they are based on.

R9 is often used in relocatable or address-independent code, when the LOADER is responsible for setting R9 to the beginning of the DATA section for a specific instance of the code, think DLLs, think thread-safe. It is going to be less prevalent on ROM based code, and will be based on settings you've used related to the compiler/linker.

Why have these variables as IO/volatile ? If they only change in this interrupt, presumably that's not going to enter multiple times.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Bizzarre maybe ... Speed difference x3 is realy bizzare. I read all i found about register variables, but STCubeIDE gcc result with code , that use register too on other places for example

0800026c <__udivmoddi4>:
 800026c:	e92d 47f0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
 8000270:	9d08      	ldr	r5, [sp, #32]
 8000272:	4604      	mov	r4, r0
 ...

Next bizzare , that i dont understand for example register sl here is r10 in arm debuger.

Variable is changed on other place , because need reset , and check it on every step isnt effective.