The builtin __builtin_ppc_get_timebase() fails to compile in VLE mode of the compiler powerpc-eabivle-gcc.exe, revision 4.9.4. The error message is:
bin/ppc/DEBUG/obj/mai_main.s:73: Error: operand out of range (7 is not between 0 and 3)
The C code is
uint64_t tiStart = __builtin_ppc_get_timebase();
The assembly listing looks like:
.loc 1 414 0
mftbu %r4 # D.18848
mftb %r5 # D.18848
mftbu %r7 #
cmpw %cr7,%r4,%r7 #, D.18848,
e_bne %cr7,$-16 #
Using CR7 seems to be not available with VLE instructions yet it is used in the instructions emitted by the compiler.
Here is my own work around. Place the code into a header file xxx....h and use XXX_PPC_GET_TIMEBASE() instead of __builtin_ppc_get_timebase():
#include <stdint.h>
#include <stdbool.h>
#ifdef __VLE__
# define XXX_PPC_GET_TIMEBASE() xxx_ppc_get_timebase()
#else
# define XXX_PPC_GET_TIMEBASE() __builtin_ppc_get_timebase()
#endif
#ifdef __VLE__
/**
* Return the world time elapsed since power up in units of CPU clock ticks. This function
* is a substitute for the GCC builtin \a __builtin_ppc_get_timebase(), which fails to compile
* with MinGW-powerpc-eabivle-4.9.4.
* @return Get the world time elapsed since power up in units of 8.333... ns; our startup
* code configures the CPU clock frequency to 120 Mhz=1/(8+1/3)ns.
* @remark
* The function is compiled only in VLE mode, use \a __builtin_ppc_get_timebase() instead
* in Book E applications.
*/
static inline uint64_t xxx_ppc_get_timebase()
{
uint32_t TBU, TBU2nd, TBL;
while(true)
{
asm volatile ( /* AssemblerTemplate */
"mfspr %0, 269\n\r" // SPR 269 = TBU
"mfspr %2, 268\n\r" // SPR 268 = TBL
"mfspr %1, 269\n\r" // SPR 269 = TBU
: /* OutputOperands */ "=r" (TBU), "=r" (TBU2nd), "=r" (TBL)
: /* InputOperands */
: /* Clobbers */
);
if(TBU == TBU2nd)
break;
}
return ((uint64_t)TBU << 32) | TBL;
} /* End of xxx_ppc_get_timebase */
#endif
Thank you for reporting. I created a ticket for that #CMPE200GCC-183
The MCU is a MPC5643L in LSM. The compiler is commanded to generate code for e200z4.
The command line is:
C:/ProgramFiles/MinGW-powerpc-eabivle-4.9.4/bin/powerpc-eabivle-gcc.exe -c -mcpu=e200z4 -mbig-endian -mvle -mspe -misel=yes -meabi -msdata=default -G8 -mregnames -mhard-float -fshort-double -mno-string -fno-common -fno-exceptions -ffunction-sections -fdata-sections -fshort-enums -fdiagnostics-show-option -finline-functions -fzero-initialized-in-bss -fno-tree-loop-optimize -Wall -Wno-main -Wno-old-style-declaration -Winline -Wextra -Wstrict-overflow=4 -Wmissing-declarations -Wno-parentheses -Wdiv-by-zero -Wcast-align -Wformat -Wformat-security -Wignored-qualifiers -Wsign-conversion -Wsign-compare -Werror=missing-declarations -Werror=implicit-function-declaration -Wno-nested-externs -Werror=int-to-pointer-cast -Werror=pointer-sign -Werror=pointer-to-int-cast -Werror=return-local-addr -MMD -Wa,-a=bin/ppc/DEBUG/obj/gsl_systemLoad.lst -std=gnu11 -Icode/ -Icode/RTOS/ -Icode/serial/ -Icode/startup/ -DDEBUG -save-temps=obj -fverbose-asm -g3 -gdwarf-2 -Og -o bin/ppc/DEBUG/obj/gsl_systemLoad.o code/RTOS/gsl_systemLoad.c
Compiler output:
bin/ppc/DEBUG/obj/gsl_systemLoad.s: Assembler messages:
bin/ppc/DEBUG/obj/gsl_systemLoad.s:88: Error: operand out of range (7 is not between 0 and 3)
bin/ppc/DEBUG/obj/gsl_systemLoad.s:113: Error: operand out of range (7 is not between 0 and 3)
Assembler listing:
.LVL0:
.loc 1 128 0
mftbu %r26 # tiStart
mftb %r27 # tiStart
mftbu %r5 #
cmpw %cr7,%r26,%r5 #, tiStart,
e_bne %cr7,$-16 #