homebrew-armeabi
homebrew-armeabi copied to clipboard
having support for cortex-m7
Hi
How difficult would it be to have support for the baremetal cortex-m7 + hard float?
Thanks
Hi,
I never worked with a M7 but it sounds it would be easy to adapt from M4/FPU: both cores use the ARMv7-EM architecture, the only noticeable difference from the ISA perspective seems to be the FPU version: v4-SP-D16 for M4, v5 for M7 - although the latter seems to exist in single and double precision variants, what a mess...
I think I read at some point that VFP versions where backward compatible, i.e. VFPv5 could execute all the instructions for VFPv4 , but I need to find this reference...
I think M4/F toolchain could generate code for a M7 w/o any change. Did you give it a try? However, FPU operation would only use single precision instructions. Are you targeting a double precision core?
Yeap I am targeting stm32f767ZI which is double precision. I did try to compile gcc myself but didn't make it work correctly. I thought that multilib could be a way to make it compatible with hard and soft and all variant of VFP but haven't been able to figure out how to configure it properly.
My guess was that clang make a mess there.
I'm not sure to understand what you meant: what kind of mess?
Using an awful C snippet such as
// this ugly piece of code is only written as a compact way
// to generate VFP ARM instructions, not to compute anything useful
int main(int argc, char ** argv)
{
double x = 1.05e-6;
double y = 2.0e+18;
int a;
double * c = (double *)argv;
double b = c[0] < c[1] ? c[0] : c[1];
if (argc != 1) {
a = (int)(b*x);
} else {
a = (int)(b*y);
}
return a;
}
and the following command line:
/usr/local/opt/arm-none-eabi-llvm/bin/clang -mcpu=cortex-m7 -mthumb -mabi=aapcs \
-mfloat-abi=hard -mfpu=fpv5-d16 -g -Os -c m7vfp.c
the output file seems to match the expected format:
$ arm-none-eabi-readelf -A m7vfp.o
Attribute Section: aeabi
File Attributes
Tag_conformance: "2.09"
Tag_CPU_name: "cortex-m7"
Tag_CPU_arch: v7E-M
Tag_CPU_arch_profile: Microcontroller
Tag_ARM_ISA_use: No
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: FPv5/FP-D16 for ARMv8
Tag_ABI_PCS_R9_use: V6
Tag_ABI_PCS_GOT_use: direct
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small
Tag_ABI_VFP_args: VFP registers
Tag_ABI_optimization_goals: Prefer Size
Tag_CPU_unaligned_access: None
Tag_FP_HP_extension: Allowed
Tag_ABI_FP_16bit_format: IEEE 754
There is this nasty ARMv8-A VFP format, but I'm not sure it is not a limitation of the ELF decoder
and the generated object file disassembles into
$ arm-none-eabi-objdump -d m7vfp.o
m7vfp.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <main>:
0: ec91 0b04 vldmia r1, {d0-d1}
4: a20a add r2, pc, #40 ; (adr r2, 30 <main+0x30>)
6: 2801 cmp r0, #1
8: bf08 it eq
a: 3208 addeq r2, #8
c: ed92 2b00 vldr d2, [r2]
10: eeb4 1bc0 vcmpe.f64 d1, d0
14: eef1 fa10 vmrs APSR_nzcv, fpscr
18: fe30 0b01 vselgt.f64 d0, d0, d1
1c: ee22 0b00 vmul.f64 d0, d2, d0
20: eebd 0bc0 vcvt.s32.f64 s0, d0
24: ee10 0a10 vmov r0, s0
28: 4770 bx lr
2a: bf00 nop
2c: bf00 nop
2e: bf00 nop
30: 358bd307 .word 0x358bd307
34: 3eb19db7 .word 0x3eb19db7
38: 674ec800 .word 0x674ec800
3c: 43bbc16d .word 0x43bbc16d
If I'm not mistaken, some VFP instructions such as vsel
are only part of the VFP v5 ISA, as expected. Using -mcpu=cortex-m4 -mfpu=fpv4-sp-d16
leads to a very different ASM code.
Now compiling another C snipped using the math library:
#include <math.h>
// again, for generating code purpose - only
// using an external ref such as argv prevents the compiler's optimiser
// to simplify the call
int main(int argc, char ** argv)
{
double * c = (double *)argv;
double s = sin(c[0]);
return (int)s;
}
and compiling/linking with
/usr/local/opt/arm-none-eabi-llvm/bin/clang -mcpu=cortex-m7 -mthumb -mabi=aapcs \
-mfloat-abi=hard -mfpu=fpv5-d16 -g -Os \
-I .../armv7em-none-eabi/cortex-m7f/include -L .../armv7em-none-eabi/cortex-m7f/lib \
m7vfp.c
give a ELF executable with match the expected format:
$ arm-none-eabi-readelf -A a.out
Attribute Section: aeabi
File Attributes
Tag_conformance: "2.09"
Tag_CPU_name: "cortex-m7"
Tag_CPU_arch: v7E-M
Tag_CPU_arch_profile: Microcontroller
Tag_ARM_ISA_use: No
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: FPv5/FP-D16 for ARMv8
Tag_ABI_PCS_R9_use: V6
Tag_ABI_PCS_GOT_use: direct
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small
Tag_ABI_VFP_args: VFP registers
Tag_ABI_optimization_goals: Prefer Size
Tag_CPU_unaligned_access: None
Tag_FP_HP_extension: Allowed
Tag_ABI_FP_16bit_format: IEEE 754
and the math library does use VFP5-d16 as well (vseleq
instructions, for example).
BTW: https://github.com/eblot/homebrew-armeabi/blob/master/armv7em-cortex-m7f.rb