GCC optimalizace, zahada

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Pátek Listopad 3 20:08:11 CET 2017


Mam kod pro plneni displeje pripojeneho osmibitove k STM32F303, bity 
jsou namixovany na ruzne porty tak to neni uplne jednoduche. Po zapnuti 
optimalizace mi to zacne asi vynechavat nastaveni nekterych bitu, barvy 
jsou spatne, nefunguje to se zakomentovanym makrem APPLYDOREGS, tak jak 
to je to unguje OK. Pomuze take vypnout optimalizaci nebo AH,AL... 
definovat jako volatile.

assembler je pri optimalizaci strasnej gulas, na prvni pohled se lisi 
kody pouzitim str vs str.w - jaky je v tom rozdil? Mel jsem za to, ze 
jen v delce kodu instrukce, kdyz jsou operace s registry... napr.:

08001720:   str     r5, [r3, #24]
08001722:   str     r1, [r4, #24]
08001724:   str.w   r6, [r8, #24]

Tusi nekdo cim to je? GPIOx->BSRR je snad definovano jako volatile 
uint32_t. Reseni mam ale znervoznuje me to...

#pragma GCC push_options
#pragma GCC optimize ("O3")


#define PREPAREDOREGS(A,B,C,v)    A =  ((v)&0x01) ? TFT_D0_Pin : 
TFT_D0_Pin << 16;\
                                 C =  ((v)&0x02) ? TFT_D1_Pin : 
TFT_D1_Pin << 16;\
                                 A |= ((v)&0x04) ? TFT_D2_Pin : 
TFT_D2_Pin << 16;\
                                 B =  ((v)&0x08) ? TFT_D3_Pin : 
TFT_D3_Pin << 16;\
                                 B |= ((v)&0x10) ? TFT_D4_Pin : 
TFT_D4_Pin << 16;\
                                 B |= ((v)&0x20) ? TFT_D5_Pin : 
TFT_D5_Pin << 16;\
                                 B |= ((v)&0x40) ? TFT_D6_Pin : 
TFT_D6_Pin << 16;\
                                 A |= ((v)&0x80) ? TFT_D7_Pin : 
TFT_D7_Pin << 16

#define APPLYDOREGS(A,B,C)    *(uint32_t *)(&GPIOA->BSRR) = A;\
                             *(uint32_t *)(&GPIOB->BSRR) = B;\
                             *(uint32_t *)(&GPIOC->BSRR) = C

//#define APPLYDOREGS(A,B,C)    GPIOA->BSRR = A;\
//                            GPIOB->BSRR = B;\
//                            GPIOC->BSRR = C

static void TftFillData (uint16_t w, int len)
{
     uint32_t AH,AL,BH,BL,CH,CL;

     TFT_RS_TPYA_GPIO_Port->BRR = TFT_RS_TPYA_Pin;
     TFT_NCS_GPIO_Port->BRR = TFT_NCS_Pin;
     PREPAREDOREGS(AH, BH, CH, 0x2c);
     APPLYDOREGS(AH, BH, CH);
     TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
     __DSB();
     __ISB();
     TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;

     TFT_RS_TPYA_GPIO_Port->BSRR = TFT_RS_TPYA_Pin;
     PREPAREDOREGS(AH, BH, CH, (uint8_t)(w >> 8));
     PREPAREDOREGS(AL, BL, CL, (uint8_t)(w & 0xff));
     while (len--)
     {
         APPLYDOREGS(AH, BH, CH);
         TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
         __DSB();
         __ISB();
         TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;

         APPLYDOREGS(AL, BL, CL);
         TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
         __DSB();
         __ISB();
         TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
     }
     TFT_NCS_GPIO_Port->BSRR = TFT_NCS_Pin;
}



Další informace o konferenci Hw-list