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.

Hard FPU unsupported instruction - vcvt.f64.f32

Hello

I am developing for tm4c123g MCU using GCC toolchain with hard FPU. I've encountered a hard fault while making some calculations. After some investigation I've came up with a sample function that is causing such a fault:

int32_t crash(float f, uint32_t u)
{
	int64_t tmp;
	tmp = f * u;       //<---- This line is generating the fault
	return (int32_t)tmp;
}

Here is a part of disassembly, that is generating the fault:

           __fixunssfdi:
00004158:    vldr d5, [pc, #52]      ; 0x4190 <__fixunssfdi+56>
0000415c:    vmov s9, r0
00004160:    vldr d6, [pc, #52]      ; 0x4198 <__fixunssfdi+64>
00004164:    vcvt.f64.f32 d7, s9   ; <-------- This line is generating the fault
00004168:    vmul.f64 d5, d7, d5
0000416c:    vcvt.u32.f64 s9, d5
00004170:    movs r0, #0

So as I understand, the instruction vcvt.f64.f32 is unsupported on this FPU. Is that right? Is there a way of tellin GCC not to generate it ? Any other solution (well, I have a workaround by playing with different types and conversions, but I would like to avoid such a problems in the future, since it is rather innocently looking code...). 

Thank you

  • Hello Evgene,

    Is the FPU Unit and Lazy Stacking Enabled?

    Regards

    Amit

  • Hi Amit.

    The FPU is enabled and working, since some other FPU instructions doing well. I am not sure about lazy stacking, will check it tomorrow, but I think it is on default state which is on AFAIK. Should it be off? Why would it matter?

    Thank you

  • Hello Evgene,

    It is not enabled by default, so having it on would be useful. I have seen such a problem in the past on FPU instruction and got it fixed using the Lazy Stacking. Also if you can send the gcc compile and link options, I can try to reproduce the same with the code snippet.

    Regards

    Amit

  • If I understand this correctly, the cause is an unsupported double precision instruction (VCVT.F64).

  • Hello f.m.

    Yes, you are right "right deserve a verified answer". It seems that the FPU option is used for a cortex-r4/5 series will generate the instruction. I do want to make sure that once we get the compilation/link options in gcc it turns out to be the use of r4 cpu option.

    Regards

    Amit

  • Thank you for your replies

    Since I am using eclipse to manage my build configs, I'll just post here just the command outputs from the console, sorry for the mess:

    make all 
    'Building file: ../src/main.c'
    'Invoking: Cross ARM C Compiler'
    arm-eabi-gcc -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wall  -g3 -DTARGET_IS_TM4C123_RB1 -DPART_TM4C123GH6PM -D__FPU_PRESENT -I"C:\Projects\Gen2_TI\driver" -I"C:\ti\TivaWare_C_Series" -std=gnu11 -MMD -MP -MF"src/main.d" -MT"src/main.o" -c -o "src/main.o" "../src/main.c"
    ../src/main.c: In function 'main':
    ../src/main.c:29:14: warning: unused variable 'r' [-Wunused-variable]
         uint32_t r = crash(0.22, 156);
                  ^
    'Finished building: ../src/main.c'
    ' '
    'Building file: ../src/startup_gcc.c'
    'Invoking: Cross ARM C Compiler'
    arm-eabi-gcc -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wall  -g3 -DTARGET_IS_TM4C123_RB1 -DPART_TM4C123GH6PM -D__FPU_PRESENT -I"C:\Projects\Gen2_TI\driver" -I"C:\ti\TivaWare_C_Series" -std=gnu11 -MMD -MP -MF"src/startup_gcc.d" -MT"src/startup_gcc.o" -c -o "src/startup_gcc.o" "../src/startup_gcc.c"
    'Finished building: ../src/startup_gcc.c'
    ' '
    'Building target: fpu_test.elf'
    'Invoking: Cross ARM C Linker'
    arm-eabi-gcc -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wall  -g3 -T "C:\Projects\Gen2_TI\fpu_test\linkerscript\tm4c123g.ld" -nostartfiles -Xlinker --gc-sections -L"C:\Projects\Gen2_TI\driver\Debug" -Wl,-Map,"fpu_test.map" -o "fpu_test.elf"  ./src/main.o ./src/startup_gcc.o   -ldriver
    'Finished building target: fpu_test.elf'

    For the sake of completenessI've attached the sources and the linker script 8306.src.zip .

  • Just an update.

    I have switched to a different toolchain build, and it is generating a different code for the same settings, such that this issue does not present anymore.

    The toolchain with the problem is this

    The "good" toolchain is this

  • Hello Evgene

    The problematic toolchain does not support M4F it seems so it reverts to R4F which has a different Floating point architecture. See the readme file in the working tool chain.

    Regards

    Amit