ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to and logged at, code of conduct at
IlPalazzo-ojiisa has quit [Ping timeout: 260 seconds]
PhilMarkgraf[m] has quit [Quit: Idle timeout reached: 172800s]
starblue has quit [Ping timeout: 255 seconds]
starblue has joined #rust-embedded
wyager[m] has joined #rust-embedded
<wyager[m]> What's the story with double-precision floating point on ARM? I'm using an STM32H747, which according to the datasheet supports double precision. I have some code using f64, but grepping the generated assembly, I see a lot of instructions like vmul.f32 but no vmul.f64. Do I have to tell rustc to set the FPU to FPv5-DP-D16-M or something?
adamgreig[m] has joined #rust-embedded
<adamgreig[m]> yes, pass -C target-feature=+fp64 or -C target-cpu=cortex-m7
relia1[m] has quit [Quit: Idle timeout reached: 172800s]
<wyager[m]> <adamgreig[m]> "yes, pass -C target-feature=+fp..." <- Thank you. It looks like the `+fp64` is necessary. Just specifying m7 doesn't do it. Interestingly, something complains "warning: unknown and unstable feature specified for `-Ctarget-feature`: `fp64`", but it looks like the generated assembly contains these instructions now
GrantM11235[m] has quit [Quit: Idle timeout reached: 172800s]
IlPalazzo-ojiisa has joined #rust-embedded
IlPalazzo-ojiisa has quit [Ping timeout: 255 seconds]
IlPalazzo-ojiisa has joined #rust-embedded
thejpster[m] has joined #rust-embedded
<thejpster[m]> I think non fpu, single or single+double fp is a configuration option when you licence the core from arm
<thejpster[m]> We only have soft and hard float ABI as targets, and we just assume if you want soft float you have no fpu and if you want hard float you have the single precision fpu.
IlPalazzo-ojiisa has quit [Ping timeout: 255 seconds]
IlPalazzo-ojiisa has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]
M9names[m] has joined #rust-embedded
<M9names[m]> the quartiq folks used a different feature. +fp64 looks like it selects vfp2, where +fp-armv8d16 selects vfp5 with double precision and +fp-armv8d16sp is the single precision option.
<adamgreig[m]> this keeps coming up it seems! the rust target file talks about +fp64 here,
<adamgreig[m]> but it didn't get merged because the branch it was PR'd against got closed instead, and later someone else wrote a different thumb platform file here which doesn't talk about it at all
<adamgreig[m]> should it actually say +fp-armv8d16?
<M9names[m]> I would think so? The baseline makes sense (runs on both m4 and m7, useful for an mcu with both) but adding +fp64 means it can't run on m4, but also can't use everything that's available for m7.
<M9names[m]> doesn't provide a lot of detail about the difference from vfp4 -> vfp5, maybe it doesn't matter much?
ello has quit [Quit: ZNC 1.8.2 -]
<wyager[m]> <adamgreig[m]> "should it actually say +fp-..." <- This flag also seems to generate the desired instructions, although I still get the unknown feature warning
therealprof[m] has quit [Quit: Idle timeout reached: 172800s]
corecode has quit [Quit: ZNC -]
<thejpster[m]> I think Cortex-M7 has an VFP5, not an Armv8 FPU, so I wouldn't suggest fp-armv8d16 for a Cortex-M7
<thejpster[m]> GCC at least has different options for the Armv8 FPU and the v5 FPU:
<thejpster[m]> We need to write this up, run a bunch of tests, and get the target readme updated.
<thejpster[m]> You can see a list of supported features with:rustc --target=thumbv7em-none-eabihf --print target-features
<thejpster[m]> It distinguishes between "features supported by rustc for this target", and "codegen features supported by LLVM for this target"
<thejpster[m]> fp64 and m7 are LLVM options, fp-armv8 is a rustc option. I have no idea why.
<thejpster[m]> By default, thumbv7em-none-eabihf enables  "features": "+vfp4,-d32,-fp64",
<thejpster[m]> (d32: Extend FP to 32 double registers, fp64: Floating point unit supports double precision)
richardeoin has quit [Ping timeout: 252 seconds]
richardeoin has joined #rust-embedded
<thejpster[m]> Ugh I fell down the rabbit hole
<thejpster[m]> A vfp4-sp-d16 FPU can hold 16 double precision numbers but can’t do arithmetic on any of them, as it can only do single precision arithmetic. Still useful for argument passing I suppose.
<thejpster[m]> And cortex-m7 cpu type is still broken in LLVM because it unconditionally enables vfp5-d16 (I.e. double precision FPU instructions), even on a soft float target.
<thejpster[m]> And cortex-m-rt won’t enable your FPU so you’ll just have a bunch of pain.
<thejpster[m]> I’m going to write all this up.
Guest7282 has left #rust-embedded [Error from remote client]
<thejpster[m]> good grief, when did [Cortex-M52]( turn up?!
ithinuel[m] has joined #rust-embedded
<ithinuel[m]> A few months back.
<thejpster[m]> the thumbv8m.main-none-eabi is absurdly overloaded - M33, M52, M55 and M85. Optional DSP, Integer Helium, Floating Point Helium, and FPU.
<M9names[m]> <thejpster[m]> "fp64 and m7 are LLVM options, fp..." <- Did you see line 174 of the LLVM code I linked, that maps "+fp-armv8d16" to FPUVersion::VFPV5? I believe that's what rustc is calling.
<thejpster[m]> that is ... confusing
<thejpster[m]> because the M7 is definitely an Armv7E-M architecture implementation
<thejpster[m]> maybe fp-armv8 and VFP5 are effectively the same
<thejpster[m]> there's certainly no vfp5 rustc flag
<thejpster[m]> CPU=M33 turns on VFP5, CPU=M55 turns on FP_ARMV8_FULLFP16_D16
<thejpster[m]> Given some -C target-cpu=cortex-m55 option, is it possible to see which target-features are enabled by that?
<thejpster[m]> I tried #[cfg(target_feature="...")] but it doesn't work on arm
<thejpster[m]> Here's what I've come up with for Armv8-m.main:
<thejpster[m]> LLVM is pretty neat: if you give it this:... (full message at <>)
<thejpster[m]> load that co-processor, and add four f32s at a time!
<M9names[m]> Do you need that loop to be unrolled for that lowering to happen?
<thejpster[m]> you need opt-level 3, yeah
<thejpster[m]> There's two kinds of Helium (aka M-Profile Vector Extensions) - integer only, and integer+float capable. +mve and +mve.fp. Even the integer one can turn:... (full message at <>)
<thejpster[m]> although that 512 byte offset on r0 looks mighty weird. I wonder if any of this stuff is actually correct.
ello has joined #rust-embedded