This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS v6 instructions reordering in assembly

Other Parts Discussed in Thread: EK-TM4C123GXL

I'm exploring a TM4C123GLX Launchpad, using CCS v6 with the TivaWare C driver library.

I'm baffled at the seemingly liberal amount of instruction reordering that the C compiler is doing in the generated assembly, even at the Debug level. My setup is as follows:

  • I have added the Examples directory of TivaWare to the TI Resource Explorer
  • I cloned an example project from the Examples/Boards/ek-tm4c123gxl directory
  • I'm using the default "Debug" build configuration
  • I'm using the function-style of the peripheral driver library of TivaWare
  • An example of the code is as follows:
uint32_t pad, strength;

MAP_GPIOPinTypeSSI(GPIO_PORTB_BASE,
                   GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7);
// The FSS pin (CS) we handle by software
MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5);
spi_cs_clear();

// Set weak pull downs on the output
MAP_GPIOPadConfigGet(GPIO_PORTB_BASE, GPIO_PIN_7,
                     &strength, &pad);

MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_7,
                     strength,
                     GPIO_PIN_TYPE_STD_WPU);

However, in the debugger view the annotated generated assembly is:

194           MAP_GPIOPinTypeSSI(GPIO_PORTB_BASE,
000006ca:   6A20     LDR             R0, [R4, #32]
203           MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_7,
000006cc:   4D21     LDR             R5, $C$CON12
194           MAP_GPIOPinTypeSSI(GPIO_PORTB_BASE,
000006ce:   6CC0     LDR             R0, [R0, #76]
...
000006d6:   4790     BLX             R2
197           MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5);
000006d8:   6A20     LDR             R0, [R4, #32]
...
000006e2:   4790     BLX             R2
198           spi_cs_clear();
000006e4:   6A20     LDR             R0, [R4, #32]
...
000006f0:   4798     BLX             R3
201           MAP_GPIOPadConfigGet(GPIO_PORTB_BASE, GPIO_PIN_7,
000006f2:   6A20     LDR             R0, [R4, #32]
...
00000700:   47B0     BLX             R6
203           MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_7,
00000702:   6A20     LDR             R0, [R4, #32]
..
00000710:   47B0     BLX             R6

Do you notice how MAP_GPIOPadConfigGet is absurdly executed after MAP_GPIOPadConfigSet, when it is clearly otherwise in the code? And this is not the only instance of this situation. So, is there some preprocesor directive or something that wll force the compiler to generate the assembly following the exact same order I wrote in my C source?


Thanks in advance!

  • Hello Luis,

    Have you enabled the ROM Mapping or are you using the Flash Version?

    Regards

    Amit

  • Hi Amit,


    As far as I could gather, what I need to do is include rom.h and rom_map.h, which I did. I guess that enables the ROM Mapping, right?

    Thanks!

    Luis

  • Hello Luis

    Yes. If the functions have a ROM equivalent it will. Remove the MAP_ prefix and then you should get the Flash Assembled driver files.

    Regards

    Amit

  • Luis Linares said:
    Do you notice how MAP_GPIOPadConfigGet is absurdly executed after MAP_GPIOPadConfigSet, when it is clearly otherwise in the code?

    Based upon the posted fragment, which skips some assembly instructions, I can't tell if the actual call to the functions has been re-ordered, or if the compiler optimizer has just re-ordered some instructions prior to the actual function calls (BLX instructions).

    Luis Linares said:
    So, is there some preprocesor directive or something that wll force the compiler to generate the assembly following the exact same order I wrote in my C source?

    Under CCS Project Properties -> Build -> ARM Compiler -> Optimization set the "Optimization Level (--opt_level, -O)" to "off".

  • Hi Chester,

    Chester Gillon said:
    Based upon the posted fragment, which skips some assembly instructions, I can't tell if the actual call to the functions has been re-ordered, or if the compiler optimizer has just re-ordered some instructions prior to the actual function calls (BLX instructions).

    Indeed I skipped the instructions in between a block (only and precisely were I put ellipsis "...", ), but I did include the BLX instructions corresponding to the C function call.

    If you check my original disasembly listing, it seems that the functions were actually executed in the proper, expected order, but the compiler simply issued "pre-emptive" LDR instructions somehow related to the functions. In the disassembly listing you find two examples:

    • the MAP_GPIOPinTypeSSI function in lines 1,2 and 5-7.
    • the MAP_GPIOPadConfigSet function in lines 3,4 and 21-24

    So this was confusing me while I was stepping over the lines. Apparently there is no issue, just an unexpected, weird, but harmless side effect.

    Chester Gillon said:
    Under CCS Project Properties -> Build -> ARM Compiler -> Optimization set the "Optimization Level (--opt_level, -O)" to "off".

    Thanks for the tip. I have considered doing that but if the library is to be useful for production work, disabling optimizations would be off-limits. It is good to keep in mind though.
  • Hi Amit,

    Sorry for the delay in replying. I removed the MAP_ prefix and after a correct build, I obtained the same behavior as that with MAP_. However, see my reply to Chester below. There might never be a harmful reordering of executions in the generated assembly, but possibly unexpected register loading prior to actually invoking the functions, where this register loading is done in advance, which generates this strange behavior while stepping over the code.

  • Hello Luis,

    I took the code into one of my programs and it generated a different dissassembly, one that seems correct in terms of LDR and BLX

    Regards

    Amit