Cortex M4 with FPU -- proper assembler defines?
This is a multi-question post.
I am using a Kinetis K60F -- so it has a FPU and Crosswoks identifies __FPU_PRESENT = 1
In file Kinetis_Startup.s the following conditional block of code exists ...
#if defined(__FPU_PRESENT) && !defined(__SOFTFP__)
// Enable CP11 and CP10 with CPACR |= (0xf<<20)
movw r0, 0xED88
movt r0, 0xE000
........
#endif
Default property value for "ARM FP ABI Type" under C code generation option is set to "SOFT"
Note -- option "ARM FP ABI Type" has 4 selections to choose from: SOFT, SOFTFP, HARD, NONE
I dump the obj file to a listing so I can see exactly what code is being generated.
When "ARM FP ABI Type" is set to SOFT -- the conditional block of code is NOT generated.
When "ARM FP ABI Type" is set to SOFTFP or HARD -- the conditional block of code IS generated.
Note -- "ARM FP ABI Type" type is NOT shown as NOT shown as a Preprocessor Definition so .....
Question #1 --- How is the "ARM FP ABI Type" being passed to the compiler?
Question #2 --- How can I view/see the compiler command string?
Question #3 --- It seems the behavior is NOT correct as __SOFTFP__ is defined when "ARM FP ABI Type" is set to SOFT instead of SOFTFP.
Thanks in advance for any comments/reply.
Joe
-
Kinetis_Startup.s
Here is the assembler code --- the concern is the behavior associated with the
Line: #if defined(__FPU_PRESENT) && !defined(__SOFTFP__)
Specifically !defined(__SOFTFP__)
If (__SOFTFP__) is NOT defined --- then the code lines:
movw r0, 0xED88
movt r0, 0xE000
should be assembled and part of the object file
.section .init, "ax"
.thumb_func
reset_handler:
#ifndef __NO_SYSTEM_INIT
#ifdef __ARM_ARCH_6M__
ldr r0, =__SRAM_segment_end__
mov sp, r0
#else
ldr sp, =__SRAM_segment_end__
#endif
bl SystemInit
#endif
#if defined(__FPU_PRESENT) && !defined(__SOFTFP__)
// Enable CP11 and CP10 with CPACR |= (0xf<<20)
movw r0, 0xED88
movt r0, 0xE000
ldr r1, [r0]
***************************************
TEST #1 ----- SOFT
-mfloat-abi=soft
000000d2 <reset_handler>:
d2: f8df d034 ldr.w sp, [pc, #52] ; 108 <reset_wait+0x8>
d6: f7ff fffe bl e4 <SystemInit>
da: 480c ldr r0, [pc, #48] ; (10c <reset_wait+0xc>)
dc: 490c ldr r1, [pc, #48] ; (110 <reset_wait+0x10>)
de: 6001 str r1, [r0, #0]
e0: f7ff fffe bl 0 <_start>
Notice that the two lines of assembler code is NOT part of the obj --- hence we can conclude that
__SOFTFP__ WAS actually defined.
NOTE: __SOFTFP__ was NOT part of the command line so I’m not sure how it is getting defined
*******************************************
TEST #2 ----- SOFTFP
-mfloat-abi=softfp
000000d2 <reset_handler>:
d2: f8df d06c ldr.w sp, [pc, #108] ; 140 <reset_wait+0x6>
d6: f7ff fffe bl 11e <SystemInit>
da: f64e 5088 movw r0, #60808 ; 0xed88
de: f2ce 0000 movt r0, #57344 ; 0xe000
e2: 6801 ldr r1, [r0, #0]
e4: f451 0170 orrs.w r1, r1, #15728640 ; 0xf00000
e8: 6001 str r1, [r0, #0]
ea: bf00 nop
ec: bf00 nop
ee: bf00 nop
f0: eef1 0a10 vmrs r0, fpscr
f4: f050 7040 orrs.w r0, r0, #50331648 ; 0x3000000
f8: eee1 0a10 vmsr fpscr, r0
fc: f04f 0000 mov.w r0, #0
100: f380 8814 msr CONTROL, r0
104: f64e 713c movw r1, #61244 ; 0xef3c
108: f2ce 0100 movt r1, #57344 ; 0xe000
10c: 6808 ldr r0, [r1, #0]
10e: f050 7040 orrs.w r0, r0, #50331648 ; 0x3000000
112: 6008 str r0, [r1, #0]
114: 480b ldr r0, [pc, #44] ; (144 <reset_wait+0xa>)
116: 490c ldr r1, [pc, #48] ; (148 <reset_wait+0xe>)
118: 6001 str r1, [r0, #0]
11a: f7ff fffe bl 0 <_start>
Notice now that the two assembler lines are part of the obj ---- hence we can conclude that
__SOFTFP__ WAS NOT defined.
**********************************
TEST #3 ---- HARD
Same result as SOFTFP
**********************************
Let me re-ask Question #3 ---
It seems that the conditional IF is not being properly compiled based on the “define status” of __SOFTFP__ compare to the value of -mfloat-abi.
The behavior appears to be reversed.
Please explain.
-
Not sure what your last post meant about #error.
The code in my post IS being correctly generated -- my question has to do with settings in Crossworks and the related generated defines.
Kinetis_Startup.s is a system file that is provided from Freescale and Crossworks uses it.
If I were browsing the source code and saw the following statement : #if defined(__FPU_PRESENT) && !defined(__SOFTFP__) --- and my Crossworks selection options for "ARM FP ABI Type were SOFT, SOFTFP, HARD, NONE --- I would have associated SOFTFP with Crossworks defining __SOFTFP__ which is NOT the case as I have demonstrated above.
Is this misassociation with Crossworks or the GNU compiler?
I was just looking for clarification as to why the reversal of SOFT and SOFT when it comes to Crossworks or the gcc compiler defining __SOFTFP__Thanks.
-
Now I understand what you are asking.
I am using a post compile process to dump the listing -- you just want to inject an error if compilation proceeds.
I placed #error after #if defined(__FPU_PRESENT) && !defined(__SOFTFP__)
When ARM FP ABI Type is SOFT -- no error
When ARM FP ABI Type is SOFTFP -- ERROR
Again -- the resulting code generation is correct -- it is just association between SOFT/SOFTFP and the resulting define of __SOFTFP__ that I am asking about.
-
I agree the code is being correctly generated for SOFT/SOFTFP/HARD.
Do you know where/how __SOFTFP__ is being defined? gcc/clang?
The behavior of __SOFTFP__ based on ARM FP ABI Type being SOFT/SOFTFP is backwards and can lead to problem is someone does not know the behavior is reversed.
That is why I asked to see the complete gcc command line to get an understanding of what is being passed to gcc.
Please sign in to leave a comment.
Comments
10 comments