Use additive offsets

OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.

Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.

Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.

Here are the results for the cc2538-demo example:
 - Compilation of uart_init():
    * before:
        REG(regs->base | UART_CC) = 0;
        200b78:	f446 637c 	orr.w	r3, r6, #4032	; 0xfc0
        200b7c:	f043 0308 	orr.w	r3, r3, #8
        200b80:	2200      	movs	r2, #0
        200b82:	601a      	str	r2, [r3, #0]

    * now:
        REG(regs->base + UART_CC) = 0;
        200b7a:	2300      	movs	r3, #0
        200b7c:	f8c4 3fc8 	str.w	r3, [r4, #4040]	; 0xfc8

 - Size of the .text section:
    * before:	0x4c7c
    * now:	0x4c28
    * saved:	84 bytes

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
Benoît Thébaudeau 2015-03-28 17:16:17 +01:00
parent c76316adf2
commit 19fd7a3551
7 changed files with 65 additions and 65 deletions

View file

@ -50,10 +50,10 @@ void halInternalGetMfgTokenData(void *data, uint16_t ID, uint8_t index, uint8_t
MEMCOPY(ram, eui64, 8 /*EUI64_SIZE*/);
} else {
//read from the Information Blocks. The token ID is only the
//bottom 16bits of the token's actual address. Since the info blocks
//exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END, we need
//to OR the ID with DATA_BIG_INFO_BASE to get the real address.
uint32_t realAddress = (DATA_BIG_INFO_BASE|ID) + (len*index);
//DATA_BIG_INFO_BASE-relative 16-bit offset of the token. Since the
//info blocks exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END,
//we need to add the ID to DATA_BIG_INFO_BASE to get the real address.
uint32_t realAddress = (DATA_BIG_INFO_BASE+ID) + (len*index);
uint8_t *flash = (uint8_t *)realAddress;
@ -77,7 +77,7 @@ void halInternalGetMfgTokenData(void *data, uint16_t ID, uint8_t index, uint8_t
void halInternalSetMfgTokenData(uint16_t token, void *data, uint8_t len)
{
StStatus flashStatus;
uint32_t realAddress = (DATA_BIG_INFO_BASE|token);
uint32_t realAddress = (DATA_BIG_INFO_BASE+token);
uint8_t * flash = (uint8_t *)realAddress;
uint32_t i;